From 252e3a2f5001781dd3b547b7d0d7af59f6dcf2be Mon Sep 17 00:00:00 2001
From: Olivier Langella <Olivier.Langella@moulon.inra.fr>
Date: Tue, 28 Mar 2017 11:11:25 +0200
Subject: [PATCH] count specific and specific unique

---
 src/CMakeLists.txt                            |   2 +
 src/core/identificationgroup.cpp              |  15 ++-
 src/core/proteinmatch.cpp                     |  18 +++
 src/core/proteinmatch.h                       |  17 ++-
 src/grouping/groupinggroup.cpp                | 109 ++++++++++++++++++
 src/grouping/groupinggroup.h                  |  51 ++++++++
 .../protein_list_view/proteintablemodel.cpp   |  32 +++--
 src/utils/groupstore.cpp                      |  58 ++++++++++
 src/utils/groupstore.h                        |  48 ++++++++
 9 files changed, 333 insertions(+), 17 deletions(-)
 create mode 100644 src/grouping/groupinggroup.cpp
 create mode 100644 src/grouping/groupinggroup.h
 create mode 100644 src/utils/groupstore.cpp
 create mode 100644 src/utils/groupstore.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 15653c620..9bc5d36a9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -65,8 +65,10 @@ SET(CPP_FILES
   core/identification_sources/identificationxtandemfile.cpp
   files/xpipfile.cpp
   grouping/groupingexperiment.cpp
+  grouping/groupinggroup.cpp
   grouping/groupingpeptidemass.cpp
   input/xpipsaxhandler.cpp
+  utils/groupstore.cpp
   utils/peptidestore.cpp
   utils/proteinstore.cpp
   utils/readspectrum.cpp
diff --git a/src/core/identificationgroup.cpp b/src/core/identificationgroup.cpp
index c4717b3ef..059fc9d65 100644
--- a/src/core/identificationgroup.cpp
+++ b/src/core/identificationgroup.cpp
@@ -23,6 +23,7 @@
 
 #include "identificationgroup.h"
 #include "project.h"
+#include "../utils/groupstore.h"
 
 
 IdentificationGroup::IdentificationGroup(Project * project)
@@ -55,7 +56,7 @@ void IdentificationGroup::addMsRunIdSp(pappso::MsRunIdSp ms_run_sp) {
     _ms_run_list.push_back(ms_run_sp);
 }
 const std::vector<pappso::MsRunIdSp> & IdentificationGroup::getMsRunIdSpList() const {
-  return _ms_run_list;
+    return _ms_run_list;
 }
 std::vector<ProteinMatch *> & IdentificationGroup::getProteinMatchList() {
     return _protein_match_list;
@@ -87,11 +88,13 @@ void IdentificationGroup::startGrouping (const GroupingType & grouping_type) {
     }
     _p_grp_experiment = GroupingExperiment::newInstance(grouping_type);
     for (auto & p_protein_match : _protein_match_list) {
-      p_protein_match->setGroupingExperiment(_p_grp_experiment);
+        p_protein_match->setGroupingExperiment(_p_grp_experiment);
     }
-    
+
     _p_grp_experiment->startGrouping();
-    
-    //remove contaminant groups
-    // renumbering
+    GroupStore group_store;
+    for (auto & p_protein_match : _protein_match_list) {
+        p_protein_match->setGroupInstance(group_store);
+    }
+
 }
diff --git a/src/core/proteinmatch.cpp b/src/core/proteinmatch.cpp
index 83871216e..ae009c04d 100644
--- a/src/core/proteinmatch.cpp
+++ b/src/core/proteinmatch.cpp
@@ -113,6 +113,10 @@ std::vector<PeptideMatch *> & ProteinMatch::getPeptideMatchList() {
     return _peptide_match_list;
 }
 
+const std::vector<PeptideMatch *> & ProteinMatch::getPeptideMatchList() const {
+    return _peptide_match_list;
+}
+
 void ProteinMatch::setGroupingExperiment(GroupingExperiment * p_grp_experiment) {
     _sp_grp_protein = nullptr;
     if (isValidAndChecked()) {
@@ -181,3 +185,17 @@ pappso::pappso_double ProteinMatch::getCoverage() const {
     //qDebug() << "ProteinMatch::getCoverage count=" << count << " prot_size=" << prot_size;
     return (((pappso::pappso_double)count)/ ((pappso::pappso_double)prot_size));
 }
+const GroupingGroupSp & ProteinMatch::getGroupingGroupSp() const {
+  return _sp_group;
+}
+
+void ProteinMatch::setGroupInstance(GroupStore & group_store) {
+    _sp_group = nullptr;
+    if (_sp_grp_protein != nullptr) {
+        unsigned int group_number = _sp_grp_protein.get()->getGroupNumber();
+        if (group_number > 0) {
+            _sp_group = group_store.getInstance(group_number);
+            _sp_group.get()->add(this);
+        }
+    }
+}
diff --git a/src/core/proteinmatch.h b/src/core/proteinmatch.h
index ea42eba33..b473d43e6 100644
--- a/src/core/proteinmatch.h
+++ b/src/core/proteinmatch.h
@@ -27,12 +27,17 @@
 #include "peptidematch.h"
 #include "automaticfilterparameters.h"
 #include "../grouping/groupingexperiment.h"
+#include "../utils/groupstore.h"
+#include "../grouping/groupinggroup.h"
 
 #ifndef PROTEINMATCH_H
 #define PROTEINMATCH_H
 
+class IdentificationGroup;
+
 class ProteinMatch
 {
+  friend IdentificationGroup;
 public:
     ProteinMatch();
     ~ProteinMatch();
@@ -44,6 +49,7 @@ public:
     void setProteinXtpSp(ProteinXtpSp protein_sp);
     void addPeptideMatch(PeptideMatch * peptide_match);
     std::vector<PeptideMatch *> & getPeptideMatchList();
+    const std::vector<PeptideMatch *> & getPeptideMatchList() const;
     void setChecked(bool arg1);
 
     bool isChecked() const;
@@ -62,17 +68,22 @@ public:
     size_t countUniqueSequence()const;
 
 
-
+    const pappso::GrpProteinSp & getGrpProteinSp() const;
+    const GroupingGroupSp & getGroupingGroupSp() const;
+    
+protected :
+ 
     /** @brief validate or invalidate peptides and proteins based automatic filters and manual checks
     * */
     void updateAutomaticFilters(const AutomaticFilterParameters & automatic_filter_parameters);
 
     void setGroupingExperiment(GroupingExperiment * p_grp_experiment);
-
-    const pappso::GrpProteinSp & getGrpProteinSp() const;
+ 
+    void setGroupInstance(GroupStore & group_store);
 
 private:
     pappso::GrpProteinSp _sp_grp_protein;
+    GroupingGroupSp _sp_group;
 
     std::vector<PeptideMatch *> _peptide_match_list;
     ProteinXtpSp _protein_sp = nullptr;
diff --git a/src/grouping/groupinggroup.cpp b/src/grouping/groupinggroup.cpp
new file mode 100644
index 000000000..cd030733c
--- /dev/null
+++ b/src/grouping/groupinggroup.cpp
@@ -0,0 +1,109 @@
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp 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 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <olivier.langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#include "groupinggroup.h"
+#include <core/proteinmatch.h>
+#include <core/peptidematch.h>
+#include <set>
+
+GroupingGroup::GroupingGroup()
+{
+
+}
+
+GroupingGroup::~GroupingGroup()
+{
+
+}
+
+
+std::size_t GroupingGroup::countSpecificSpectrum(const ProteinMatch * p_protein_match) const {
+    if (_number_of_subgroup == 1) {
+        return p_protein_match->countValidAndCheckedSpectrum();
+    }
+    std::set<QString> spectrum_list_in;
+    for (auto && p_peptide_match :p_protein_match->getPeptideMatchList()) {
+        if (p_peptide_match->isValidAndChecked()) {
+            spectrum_list_in.insert(QString("%1-%2").arg(p_peptide_match->getMsRunIdSp().get()->getXmlId()).arg(p_peptide_match->getScan()));
+        }
+    }
+    std::set<QString> spectrum_list_out;
+    unsigned int sg_number = p_protein_match->getGrpProteinSp().get()->getSubGroupNumber();
+    for (auto && pair_peptide_match :_pair_sg_number_peptide_match_list) {
+        if (pair_peptide_match.first != sg_number) {
+            spectrum_list_out.insert(QString("%1-%2").arg(pair_peptide_match.second->getMsRunIdSp().get()->getXmlId()).arg(pair_peptide_match.second->getScan()));
+        }
+    }
+
+    std::size_t count = 0;
+    for (const QString & spectrum: spectrum_list_in) {
+        std::set<QString>::const_iterator it = spectrum_list_out.find(spectrum);
+        if (it == spectrum_list_out.end()) {
+            count++;
+        }
+    }
+    return count;
+}
+
+std::size_t GroupingGroup::countSpecificSequence(const ProteinMatch * p_protein_match) const {
+    if (_number_of_subgroup == 1) {
+        return p_protein_match->countUniqueSequence();
+    }
+    std::set<QString> sequence_list_in;
+    for (auto && p_peptide_match :p_protein_match->getPeptideMatchList()) {
+        if (p_peptide_match->isValidAndChecked()) {
+            sequence_list_in.insert(p_peptide_match->getPeptideXtpSp().get()->getSequence());
+        }
+    }
+    std::set<QString> sequence_list_out;
+    unsigned int sg_number = p_protein_match->getGrpProteinSp().get()->getSubGroupNumber();
+    for (auto && pair_peptide_match :_pair_sg_number_peptide_match_list) {
+        if (pair_peptide_match.first != sg_number) {
+            sequence_list_out.insert(pair_peptide_match.second->getPeptideXtpSp().get()->getSequence());
+        }
+    }
+
+    std::size_t count = 0;
+    for (const QString & sequence: sequence_list_in) {
+        std::set<QString>::const_iterator it = sequence_list_out.find(sequence);
+        if (it == sequence_list_out.end()) {
+            count++;
+        }
+    }
+    return count;
+}
+
+void GroupingGroup::add(const ProteinMatch * p_protein_match) {
+
+    if (p_protein_match->getGrpProteinSp().get()->getRank() == 1) {
+        _number_of_subgroup++;
+        unsigned int sg_number = p_protein_match->getGrpProteinSp().get()->getSubGroupNumber();
+
+        for (auto && p_peptide_match :p_protein_match->getPeptideMatchList()) {
+            if (p_peptide_match->isValidAndChecked()) {
+                _pair_sg_number_peptide_match_list.push_back(std::pair<unsigned int, const PeptideMatch * >(sg_number, p_peptide_match));
+            }
+        }
+    }
+}
+
diff --git a/src/grouping/groupinggroup.h b/src/grouping/groupinggroup.h
new file mode 100644
index 000000000..983996c7d
--- /dev/null
+++ b/src/grouping/groupinggroup.h
@@ -0,0 +1,51 @@
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp 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 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <olivier.langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#ifndef GROUPINGGROUP_H
+#define GROUPINGGROUP_H
+
+#include <memory>
+#include <vector>
+
+class ProteinMatch;
+class PeptideMatch;
+
+class GroupingGroup;
+typedef std::shared_ptr<GroupingGroup> GroupingGroupSp;
+
+class GroupingGroup
+{
+public:
+
+    GroupingGroup();
+    ~GroupingGroup();
+
+    void add(const ProteinMatch * p_protein_match);
+    std::size_t countSpecificSpectrum(const ProteinMatch * p_protein_match) const;
+    std::size_t countSpecificSequence(const ProteinMatch * p_protein_match) const;
+private :
+  unsigned int _number_of_subgroup=0;
+    std::vector<std::pair<unsigned int, const PeptideMatch *>> _pair_sg_number_peptide_match_list;
+};
+
+#endif // GROUPINGGROUP_H
diff --git a/src/gui/protein_list_view/proteintablemodel.cpp b/src/gui/protein_list_view/proteintablemodel.cpp
index 932391ea8..041e9efc2 100644
--- a/src/gui/protein_list_view/proteintablemodel.cpp
+++ b/src/gui/protein_list_view/proteintablemodel.cpp
@@ -24,6 +24,7 @@
 #include "proteintablemodel.h"
 #include "proteinlistwindow.h"
 #include <pappsomspp/grouping/grpprotein.h>
+#include "../../grouping/groupinggroup.h"
 
 #include <QDebug>
 
@@ -146,7 +147,7 @@ int ProteinTableModel::rowCount(const QModelIndex &parent ) const {
     return 0;
 }
 int ProteinTableModel::columnCount(const QModelIndex &parent ) const {
-    return 8;
+    return 10;
 }
 QVariant ProteinTableModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
@@ -168,8 +169,12 @@ QVariant ProteinTableModel::headerData(int section, Qt::Orientation orientation,
             case 5:
                 return QString("spectrum");
             case 6:
-                return QString("unique");
+                return QString("specific");
             case 7:
+                return QString("sequence");
+            case 8:
+                return QString("specific sequence");
+            case 9:
                 return QString("coverage");
             }
         }
@@ -183,6 +188,7 @@ QVariant ProteinTableModel::data(const QModelIndex &index, int role ) const {
     qDebug() << QString("row %1, col%2, role %3")
              .arg(row).arg(col).arg(role);
 
+
     switch(role) {
     case Qt::CheckStateRole:
 
@@ -237,19 +243,29 @@ QVariant ProteinTableModel::data(const QModelIndex &index, int role ) const {
 
         }
 
-        if (col == 5) {
+        if (col == 5) {//spectrum
             return QVariant ((qreal) _p_identification_group->getProteinMatchList().at(row)->countValidAndCheckedSpectrum());
         }
-        if (col == 6) {
+        if (col == 6) {//specific
+            GroupingGroup * p_groupin_group = _p_identification_group->getProteinMatchList().at(row)->getGroupingGroupSp().get();
+            if (p_groupin_group != nullptr) {
+                return QVariant ((qreal) p_groupin_group->countSpecificSpectrum(_p_identification_group->getProteinMatchList().at(row)));
+            }
+        }
+        if (col == 7) {//sequence
             return QVariant ((qreal) _p_identification_group->getProteinMatchList().at(row)->countUniqueSequence());
         }
-        if (col == 7) {
+        if (col == 8) {//specific sequence
+            GroupingGroup * p_groupin_group = _p_identification_group->getProteinMatchList().at(row)->getGroupingGroupSp().get();
+            if (p_groupin_group != nullptr) {
+                return QVariant ((qreal) p_groupin_group->countSpecificSequence(_p_identification_group->getProteinMatchList().at(row)));
+            }
+        }
+        if (col == 9) {
             return QVariant ((qreal)_p_identification_group->getProteinMatchList().at(row)->getCoverage());
         }
 
-        return QString("Row%1, Column%2")
-               .arg(index.row() + 1)
-               .arg(index.column() +1);
+        return QVariant();
     }
     return QVariant();
 }
diff --git a/src/utils/groupstore.cpp b/src/utils/groupstore.cpp
new file mode 100644
index 000000000..7f5f0ffa9
--- /dev/null
+++ b/src/utils/groupstore.cpp
@@ -0,0 +1,58 @@
+/**
+ * \file utils/groupstore.cpp
+ * \date 28/3/2017
+ * \author Olivier Langella
+ * \brief store unique version of groups
+ */
+
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <Olivier.Langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp 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 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <Olivier.Langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#include "groupstore.h"
+
+GroupStore::GroupStore()
+{
+
+}
+
+GroupStore::~GroupStore()
+{
+
+}
+
+GroupingGroupSp GroupStore::getInstance(unsigned int group_number) {
+
+    GroupingGroupSp sp_group;
+    if (group_number > 0) {
+        std::map< unsigned int, GroupingGroupSp>::iterator it = _map_group.find(group_number);
+        if (it != _map_group.end()) {
+            sp_group = it->second;
+        }
+        else {
+            sp_group = std::make_shared<GroupingGroup>();
+            _map_group.insert(std::pair<unsigned int, GroupingGroupSp>(group_number,sp_group));
+        }
+    }
+    return (sp_group);
+
+}
diff --git a/src/utils/groupstore.h b/src/utils/groupstore.h
new file mode 100644
index 000000000..051918cd4
--- /dev/null
+++ b/src/utils/groupstore.h
@@ -0,0 +1,48 @@
+/**
+ * \file utils/groupstore.h
+ * \date 28/3/2017
+ * \author Olivier Langella
+ * \brief store unique version of groups
+ */
+
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <Olivier.Langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp 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 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <Olivier.Langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#include "../grouping/groupinggroup.h"
+
+#ifndef GROUPSTORE_H
+#define GROUPSTORE_H
+
+#include <map>
+
+class GroupStore
+{
+public:
+    GroupStore();
+    ~GroupStore();
+    GroupingGroupSp getInstance(unsigned int group_number);
+private :
+    std::map<unsigned int, GroupingGroupSp> _map_group;
+};
+
+#endif // GROUPSTORE_H
-- 
GitLab