From a4bb125bdad6fb4b69bd41e520b9d8aac9c4d177 Mon Sep 17 00:00:00 2001
From: Olivier Langella <Olivier.Langella@moulon.inra.fr>
Date: Wed, 5 Apr 2017 16:06:33 +0200
Subject: [PATCH] new ms run peptide store and msrun specific object

---
 src/CMakeLists.txt                            |  6 +-
 .../identificationdatasource.cpp              |  6 +-
 .../identificationdatasource.h                |  8 +--
 src/core/identificationgroup.cpp              |  4 +-
 src/core/identificationgroup.h                |  8 +--
 src/core/msrun.cpp                            | 63 +++++++++++++++++++
 src/core/msrun.h                              | 59 +++++++++++++++++
 src/core/peptidematch.cpp                     |  4 +-
 src/core/peptidematch.h                       |  8 +--
 src/core/project.cpp                          |  4 ++
 src/core/project.h                            |  3 +
 src/core/proteinmatch.cpp                     | 34 ++++------
 src/core/proteinmatch.h                       | 17 ++---
 src/grouping/groupinggroup.cpp                |  4 +-
 .../identificationgroupwidget.cpp             |  2 +-
 src/input/xpipsaxhandler.cpp                  | 18 +++---
 src/input/xpipsaxhandler.h                    |  1 -
 src/utils/identificationdatasourcestore.h     |  1 -
 src/utils/msrunstore.cpp                      | 57 +++++++++++++++++
 src/utils/msrunstore.h                        | 49 +++++++++++++++
 src/utils/readspectrum.cpp                    | 12 ++--
 src/utils/readspectrum.h                      |  6 +-
 22 files changed, 293 insertions(+), 81 deletions(-)
 create mode 100644 src/core/msrun.cpp
 create mode 100644 src/core/msrun.h
 create mode 100644 src/utils/msrunstore.cpp
 create mode 100644 src/utils/msrunstore.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2be9885af..6d76e8269 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -55,14 +55,15 @@ configure_file (${CMAKE_SOURCE_DIR}/src/config.h.cmake ${CMAKE_SOURCE_DIR}/src/c
 SET(CPP_FILES
   core/automaticfilterparameters.cpp
   core/identificationgroup.cpp
+  core/identification_sources/identificationdatasource.cpp
+  core/identification_sources/identificationxtandemfile.cpp
+  core/msrun.cpp
   core/peptidematch.cpp
   core/peptidextp.cpp
   ./core/project.cpp
   core/proteinmatch.cpp
   core/proteinxtp.cpp
   core/sequencedatabase.cpp
-  core/identification_sources/identificationdatasource.cpp
-  core/identification_sources/identificationxtandemfile.cpp
   files/xpipfile.cpp
   grouping/groupingexperiment.cpp
   grouping/groupinggroup.cpp
@@ -71,6 +72,7 @@ SET(CPP_FILES
   input/xpipsaxhandler.cpp
   utils/identificationdatasourcestore.cpp
   utils/groupstore.cpp
+  utils/msrunstore.cpp
   utils/peptidestore.cpp
   utils/proteinstore.cpp
   utils/readspectrum.cpp
diff --git a/src/core/identification_sources/identificationdatasource.cpp b/src/core/identification_sources/identificationdatasource.cpp
index 6341285c1..a90445286 100644
--- a/src/core/identification_sources/identificationdatasource.cpp
+++ b/src/core/identification_sources/identificationdatasource.cpp
@@ -56,15 +56,15 @@ const QString IdentificationDataSource::getSampleName () const {
     return file.baseName();
 }
 
-void IdentificationDataSource::setMsRunSp (pappso::MsRunIdSp ms_run_sp) {
+void IdentificationDataSource::setMsRunSp (MsRunSp ms_run_sp) {
     _ms_run_sp = ms_run_sp;
 }
-pappso::MsRunIdSp IdentificationDataSource::getMsRunSp () const {
+MsRunSp IdentificationDataSource::getMsRunSp () const {
     return (_ms_run_sp);
 }
 
 
 pappso::SpectrumSp IdentificationDataSource::getSpectrumSp(unsigned int scan_number) const {
-    pappso::SpectrumSp spectrum_sp = SpectrumStore::getSpectrumSpFromMsRunIdSp(_ms_run_sp, scan_number);
+    pappso::SpectrumSp spectrum_sp = SpectrumStore::getSpectrumSpFromMsRunSp(_ms_run_sp, scan_number);
     return spectrum_sp;
 }
diff --git a/src/core/identification_sources/identificationdatasource.h b/src/core/identification_sources/identificationdatasource.h
index eafcb169e..7f13e9593 100644
--- a/src/core/identification_sources/identificationdatasource.h
+++ b/src/core/identification_sources/identificationdatasource.h
@@ -24,9 +24,9 @@
 #define IDENTIFICATIONDATASOURCE_H
 
 
-#include <pappsomspp/msrun/msrunid.h>
 #include <pappsomspp/spectrum/spectrum.h>
 #include <memory>
+#include "../msrun.h"
 
 
 class IdentificationDataSource;
@@ -43,8 +43,8 @@ public:
 
     const QString & getResourceName () const;
     const QString getSampleName () const;
-    void setMsRunSp (pappso::MsRunIdSp ms_run_sp);
-    pappso::MsRunIdSp getMsRunSp () const;
+    void setMsRunSp (MsRunSp ms_run_sp);
+    MsRunSp getMsRunSp () const;
     /** @brief get the spectrum with scan number
      * */
     virtual pappso::SpectrumSp getSpectrumSp(unsigned int scan_number) const;
@@ -53,7 +53,7 @@ protected :
     QString _resource_name;
 private :
     //static std::map<QString, pappso::MsRunIdSp> _map_msrunidsp;
-    pappso::MsRunIdSp _ms_run_sp = nullptr;
+    MsRunSp _ms_run_sp = nullptr;
 };
 
 #endif // IDENTIFICATIONDATASOURCE_H
diff --git a/src/core/identificationgroup.cpp b/src/core/identificationgroup.cpp
index 406c49d31..75e8d1c63 100644
--- a/src/core/identificationgroup.cpp
+++ b/src/core/identificationgroup.cpp
@@ -52,10 +52,10 @@ void IdentificationGroup::updateAutomaticFilters(const AutomaticFilterParameters
 void IdentificationGroup::addProteinMatch(ProteinMatch * protein_match) {
     _protein_match_list.push_back(protein_match);
 }
-void IdentificationGroup::addMsRunIdSp(pappso::MsRunIdSp ms_run_sp) {
+void IdentificationGroup::addMsRunSp(MsRunSp ms_run_sp) {
     _ms_run_list.push_back(ms_run_sp);
 }
-const std::vector<pappso::MsRunIdSp> & IdentificationGroup::getMsRunIdSpList() const {
+const std::vector<MsRunSp> & IdentificationGroup::getMsRunSpList() const {
     return _ms_run_list;
 }
 std::vector<ProteinMatch *> & IdentificationGroup::getProteinMatchList() {
diff --git a/src/core/identificationgroup.h b/src/core/identificationgroup.h
index cc8f03a5f..587bde926 100644
--- a/src/core/identificationgroup.h
+++ b/src/core/identificationgroup.h
@@ -23,7 +23,7 @@
 #include <memory>
 #include <QFileInfo>
 #include "proteinmatch.h"
-#include <pappsomspp/msrun/msrunid.h>
+#include "msrun.h"
 
 #include "grouping/groupingexperiment.h"
 #include "../utils/types.h"
@@ -45,7 +45,7 @@ public:
 
     void addProteinMatch(ProteinMatch * protein_match);
     std::vector<ProteinMatch *> & getProteinMatchList();
-    void addMsRunIdSp(pappso::MsRunIdSp ms_run_sp);
+    void addMsRunSp(MsRunSp ms_run_sp);
     
     /** @brief count valid proteins
      * */    
@@ -74,7 +74,7 @@ public:
     
     void startGrouping (const GroupingType & grouping_type);
     
-    const std::vector<pappso::MsRunIdSp> & getMsRunIdSpList() const; 
+    const std::vector<MsRunSp> & getMsRunSpList() const; 
     
     /** @brief get tab name for qtabwidget
      * */   
@@ -88,7 +88,7 @@ private :
 
     std::vector<ProteinMatch *> _protein_match_list;
 
-    std::vector<pappso::MsRunIdSp> _ms_run_list;
+    std::vector<MsRunSp> _ms_run_list;
 };
 
 #endif // IDENTIFICATIONGROUP_H
diff --git a/src/core/msrun.cpp b/src/core/msrun.cpp
new file mode 100644
index 000000000..f5685957b
--- /dev/null
+++ b/src/core/msrun.cpp
@@ -0,0 +1,63 @@
+/**
+ * \filed core/msrun.cpp
+ * \date 5/4/2017
+ * \author Olivier Langella
+ * \brief describes an MS run (chemical sample injected in a mass spectrometer)
+ */
+
+
+/*******************************************************************************
+* 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 "msrun.h"
+#include <QFileInfo>
+
+MsRun::MsRun(const QString & location) {
+    _xml_id = location;
+    _location = location;
+    QFileInfo fileinfo(location);
+    _name = fileinfo.baseName();
+}
+
+MsRun::MsRun(const MsRun& other) {
+    _xml_id = other._xml_id;
+    _location = other._location;
+    _name = other._name;
+}
+
+MsRun::~MsRun() {
+}
+
+
+void MsRun::setFilename(const QString filename) {
+    _location = filename;
+}
+void MsRun::setXmlId(const QString xmlid) {
+    _xml_id = xmlid;
+}
+const QString & MsRun::getXmlId() const {
+    return _xml_id;
+}
+const QString & MsRun::getFilename() const {
+    return _location;
+}
diff --git a/src/core/msrun.h b/src/core/msrun.h
new file mode 100644
index 000000000..5262b2bea
--- /dev/null
+++ b/src/core/msrun.h
@@ -0,0 +1,59 @@
+/**
+ * \filed core/msrun.h
+ * \date 5/4/2017
+ * \author Olivier Langella
+ * \brief describes an MS run (chemical sample injected in a mass spectrometer)
+ */
+
+
+/*******************************************************************************
+* 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 MSRUN_H
+#define MSRUN_H
+
+#include <memory>
+#include <QString>
+
+class MsRun;
+typedef std::shared_ptr<MsRun> MsRunSp;
+
+class MsRun
+{
+public:
+    MsRun(const QString & location);
+    MsRun(const MsRun& other);
+    ~MsRun();
+    
+    void setFilename(const QString filename);
+    void setXmlId(const QString xmlid);
+    
+    const QString & getFilename() const;
+    const QString & getXmlId() const;
+private :
+    QString _xml_id;
+    QString _location;
+    QString _name;
+};
+
+#endif // MSRUN_H
diff --git a/src/core/peptidematch.cpp b/src/core/peptidematch.cpp
index 12afc44b5..faba2b9a9 100644
--- a/src/core/peptidematch.cpp
+++ b/src/core/peptidematch.cpp
@@ -23,7 +23,7 @@
 
 #include "peptidematch.h"
 
-PeptideMatch::PeptideMatch(pappso::MsRunIdSp msrunid_sp, unsigned int scan) {
+PeptideMatch::PeptideMatch(MsRun * msrunid_sp, unsigned int scan) {
     _msrunid_sp = msrunid_sp;
     _scan = scan;
 }
@@ -109,7 +109,7 @@ const PeptideXtpSp & PeptideMatch::getPeptideXtpSp() const {
     return _peptide_sp;
 }
 
-const pappso::MsRunIdSp & PeptideMatch::getMsRunIdSp() const {
+const MsRun * PeptideMatch::getMsRunP() const {
     return _msrunid_sp;
 }
 void PeptideMatch::setGrpPeptideSp(const pappso::GrpPeptideSp & sp_grp_peptide) {
diff --git a/src/core/peptidematch.h b/src/core/peptidematch.h
index 3fd03a276..49c58b637 100644
--- a/src/core/peptidematch.h
+++ b/src/core/peptidematch.h
@@ -23,18 +23,18 @@
 
 #ifndef PEPTIDEMATCH_H
 #define PEPTIDEMATCH_H
-#include <pappsomspp/msrun/msrunid.h>
 #include <pappsomspp/types.h>
 #include "peptidextp.h"
 #include "identification_sources/identificationdatasource.h"
 #include "automaticfilterparameters.h"
+#include "msrun.h"
 
 #include "../grouping/groupingexperiment.h"
 
 class PeptideMatch
 {
 public :
-    PeptideMatch(pappso::MsRunIdSp msrunid_sp, unsigned int scan);
+    PeptideMatch(MsRun * msrunid_sp, unsigned int scan);
 
     void setRetentionTime(pappso::pappso_double rt);
     void setEvalue(pappso::pappso_double evalue);
@@ -57,7 +57,7 @@ public :
     bool isValidAndChecked() const;
     bool isGrouped() const;
 
-    const pappso::MsRunIdSp & getMsRunIdSp() const;
+    const MsRun * getMsRunP() const;
     IdentificationDataSource* getIdentificationDataSource () const;
     unsigned int getScan() const;
     pappso::pappso_double getRetentionTime() const;
@@ -77,7 +77,7 @@ public :
     pappso::mz getDeltaMass() const;
 
 private :
-    pappso::MsRunIdSp _msrunid_sp;
+    MsRun * _msrunid_sp;
     unsigned int _scan;
     pappso::GrpPeptideSp _sp_grp_peptide;
     PeptideXtpSp _peptide_sp;
diff --git a/src/core/project.cpp b/src/core/project.cpp
index 5b41ef2d9..b3fb2ea9f 100644
--- a/src/core/project.cpp
+++ b/src/core/project.cpp
@@ -44,6 +44,10 @@ std::vector<IdentificationGroup *> Project::getIdentificationGroupList() {
 const GroupingType Project::getGroupingType() const {
     return _grouping_type;
 }
+
+MsRunStore & Project::getMsRunStore() {
+    return _msrun_store;
+}
 PeptideStore & Project::getPeptideStore() {
     return _peptide_store;
 }
diff --git a/src/core/project.h b/src/core/project.h
index 9fcb09358..f00b2e41a 100644
--- a/src/core/project.h
+++ b/src/core/project.h
@@ -30,6 +30,7 @@
 #include "../utils/peptidestore.h"
 #include "../utils/proteinstore.h"
 #include "../utils/identificationdatasourcestore.h"
+#include "../utils/msrunstore.h"
 
 class Project;
 typedef std::shared_ptr<Project> ProjectSp;
@@ -46,6 +47,7 @@ public:
     ProjectSp makeProjectSp() const;
     ProteinStore & getProteinStore();
     PeptideStore & getPeptideStore();
+    MsRunStore & getMsRunStore();
     IdentificationDataSourceStore & getIdentificationDataSourceStore();
     void readXpipFile(QFileInfo xpip_source);
     IdentificationGroup* newIdentificationGroup();
@@ -72,6 +74,7 @@ private :
     ProteinStore _protein_store;
     PeptideStore _peptide_store;
     IdentificationDataSourceStore _identification_data_source_store;
+    MsRunStore _msrun_store;
 };
 
 #endif // PROJECT_H
diff --git a/src/core/proteinmatch.cpp b/src/core/proteinmatch.cpp
index 091f7ac51..1b49536a9 100644
--- a/src/core/proteinmatch.cpp
+++ b/src/core/proteinmatch.cpp
@@ -22,7 +22,6 @@
 ******************************************************************************/
 
 #include "proteinmatch.h"
-#include <pappsomspp/msrun/msrunid.h>
 #include <pappsomspp/grouping/grpprotein.h>
 #include <set>
 
@@ -66,14 +65,14 @@ void ProteinMatch::updateAutomaticFilters(const AutomaticFilterParameters & auto
         number_of_valid_peptides= countValidAndCheckedPeptide(nullptr);
     }
     else {
-        std::set<const pappso::MsRunId *> msrun_set;
+        std::set<const MsRun *> msrun_set;
         for (auto & p_peptide_match : _peptide_match_list) {
             p_peptide_match->updateAutomaticFilters(automatic_filter_parameters);
             if (p_peptide_match->isValidAndChecked()) {
-                msrun_set.insert(p_peptide_match->getMsRunIdSp().get());
+                msrun_set.insert(p_peptide_match->getMsRunP());
             }
         }
-        for (const pappso::MsRunId * p_msrun : msrun_set) {
+        for (const MsRun * p_msrun : msrun_set) {
             unsigned int count = countValidAndCheckedPeptide(p_msrun);
             if (count > number_of_valid_peptides) {
                 number_of_valid_peptides = count;
@@ -104,10 +103,6 @@ void ProteinMatch::setEvalue(pappso::pappso_double evalue) {
     _evalue = evalue;
 }
 
-pappso::pappso_double ProteinMatch::getEvalue() const {
-    pappso::MsRunIdSp sp_msrun_id;
-    return getEvalue(sp_msrun_id);
-}
 void ProteinMatch::setProteinXtpSp(ProteinXtpSp protein_sp) {
     _protein_sp = protein_sp;
 }
@@ -195,13 +190,13 @@ size_t ProteinMatch::countUniqueSequence()const {
     return sequence_list.size();
 }
 
-unsigned int ProteinMatch::countValidAndCheckedPeptide(const pappso::MsRunId * p_msrun_id) const {
+unsigned int ProteinMatch::countValidAndCheckedPeptide(const MsRun * p_msrun_id) const {
     std::set<QString> sequence_list;
     for (auto & p_peptide_match : _peptide_match_list) {
         if (p_peptide_match->isValidAndChecked()) {
             if(p_msrun_id != nullptr) {
                 //within sample
-                if (p_peptide_match->getMsRunIdSp().get() == p_msrun_id) {
+                if (p_peptide_match->getMsRunP() == p_msrun_id) {
                     sequence_list.insert(p_peptide_match->getPeptideXtpSp().get()->getSequenceLi());
                 }
             }
@@ -215,13 +210,13 @@ unsigned int ProteinMatch::countValidAndCheckedPeptide(const pappso::MsRunId * p
     return sequence_list.size();
 }
 
-unsigned int ProteinMatch::countValidAndCheckedPeptideMassCharge(const pappso::MsRunIdSp & sp_msrun_id) const {
+unsigned int ProteinMatch::countValidAndCheckedPeptideMassCharge(const MsRun * sp_msrun_id) const {
     std::set<QString> sequence_list;
     for (auto & p_peptide_match : _peptide_match_list) {
         if (p_peptide_match->isValidAndChecked()) {
-            if(sp_msrun_id.get() != nullptr) {
+            if(sp_msrun_id != nullptr) {
                 //within sample
-                if (p_peptide_match->getMsRunIdSp().get() == sp_msrun_id.get()) {
+                if (p_peptide_match->getMsRunP() == sp_msrun_id) {
                     sequence_list.insert(QString("%1-%2").arg(p_peptide_match->getPeptideXtpSp().get()->toAbsoluteString()).arg(p_peptide_match->getCharge()));
                 }
             }
@@ -234,15 +229,15 @@ unsigned int ProteinMatch::countValidAndCheckedPeptideMassCharge(const pappso::M
     return sequence_list.size();
 }
 
-pappso::pappso_double ProteinMatch::getEvalue(const pappso::MsRunIdSp & sp_msrun_id) const {
+pappso::pappso_double ProteinMatch::getEvalue(const MsRun * sp_msrun_id) const {
     std::map<QString, pappso::pappso_double> map_sequence_evalue;
     for (auto & p_peptide_match : _peptide_match_list) {
         if (p_peptide_match->isValidAndChecked()) {
             QString sequence(p_peptide_match->getPeptideXtpSp().get()->getSequence());
             pappso::pappso_double evalue = p_peptide_match->getEvalue();
-            if(sp_msrun_id.get() != nullptr) {
+            if(sp_msrun_id != nullptr) {
                 //within sample
-                if (p_peptide_match->getMsRunIdSp().get() == sp_msrun_id.get()) {
+                if (p_peptide_match->getMsRunP() == sp_msrun_id) {
                     auto ret = map_sequence_evalue.insert(std::pair<QString, pappso::pappso_double>(sequence, evalue));
                     if (ret.second == false) {
                         if (ret.first->second > evalue) {//get best evalue for sequence
@@ -274,12 +269,7 @@ pappso::pappso_double ProteinMatch::getEvalue(const pappso::MsRunIdSp & sp_msrun
 
 }
 
-pappso::pappso_double ProteinMatch::getPAI() const {
-    pappso::MsRunIdSp sp_msrun_id;
-    return getPAI(sp_msrun_id);
-}
-
-pappso::pappso_double ProteinMatch::getPAI(const pappso::MsRunIdSp & sp_msrun_id) const {
+pappso::pappso_double ProteinMatch::getPAI(const MsRun * sp_msrun_id) const {
     pappso::pappso_double PAI =  (pappso::pappso_double) countValidAndCheckedPeptideMassCharge(sp_msrun_id) / (pappso::pappso_double) _protein_sp.get()->countTrypticPeptidesForPAI();
     return PAI;
 }
diff --git a/src/core/proteinmatch.h b/src/core/proteinmatch.h
index c26932481..dfce9d760 100644
--- a/src/core/proteinmatch.h
+++ b/src/core/proteinmatch.h
@@ -46,13 +46,9 @@ public:
     const ProteinXtpSp & getProteinXtpSp() const;
     void setEvalue(pappso::pappso_double evalue);
 
-    /** @brief compute protein Evalue overall samples
-      * */
-    pappso::pappso_double getEvalue() const;
-
     /** @brief compute protein Evalue within samples
       * */
-    pappso::pappso_double getEvalue(const pappso::MsRunIdSp & sp_msrun_id) const;
+    pappso::pappso_double getEvalue(const MsRun * sp_msrun_id = nullptr) const;
 
 
     /** @brief protein coverage overall samples
@@ -64,15 +60,10 @@ public:
      **/
     const QString getHtmlSequence(PeptideMatch * peptide_match_to_locate = nullptr) const;
 
-    /** @brief compute Protein Abundance Index (PAI)
-      * overall sample PAI computation (Rappsilber et al. 2002)
-      * */
-    pappso::pappso_double getPAI() const;
-
     /** @brief compute Protein Abundance Index (PAI) within sample
      * PAI computation (Rappsilber et al. 2002)
      * */
-    pappso::pappso_double getPAI(const pappso::MsRunIdSp & sp_msrun_id) const;
+    pappso::pappso_double getPAI(const MsRun * sp_msrun_id = nullptr) const;
 
     void setProteinXtpSp(ProteinXtpSp protein_sp);
     void addPeptideMatch(PeptideMatch * peptide_match);
@@ -114,8 +105,8 @@ protected :
     void setGroupInstance(GroupStore & group_store);
 
 private :
-    unsigned int countValidAndCheckedPeptide(const pappso::MsRunId * p_msrun_id) const;
-    unsigned int countValidAndCheckedPeptideMassCharge(const pappso::MsRunIdSp & sp_msrun_id) const;
+    unsigned int countValidAndCheckedPeptide(const MsRun * p_msrun_id) const;
+    unsigned int countValidAndCheckedPeptideMassCharge(const MsRun * sp_msrun_id) const;
 
 private:
   static QColor _color_peptide_background;
diff --git a/src/grouping/groupinggroup.cpp b/src/grouping/groupinggroup.cpp
index 702aea18b..b414e3208 100644
--- a/src/grouping/groupinggroup.cpp
+++ b/src/grouping/groupinggroup.cpp
@@ -81,14 +81,14 @@ std::size_t GroupingGroup::countSpecificSpectrum(const ProteinMatch * p_protein_
     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()));
+            spectrum_list_in.insert(QString("%1-%2").arg(p_peptide_match->getMsRunP()->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()));
+            spectrum_list_out.insert(QString("%1-%2").arg(pair_peptide_match.second->getMsRunP()->getXmlId()).arg(pair_peptide_match.second->getScan()));
         }
     }
 
diff --git a/src/gui/project_view/identification_group_widget/identificationgroupwidget.cpp b/src/gui/project_view/identification_group_widget/identificationgroupwidget.cpp
index 3ffc648df..8fb21db15 100644
--- a/src/gui/project_view/identification_group_widget/identificationgroupwidget.cpp
+++ b/src/gui/project_view/identification_group_widget/identificationgroupwidget.cpp
@@ -63,7 +63,7 @@ void IdentificationGroupWidget::doViewProteinList() {
 
 void IdentificationGroupWidget::doIdentificationGroupGrouped(IdentificationGroup * p_identification_group) {
     if (_p_identification_group == p_identification_group) {
-        vector< pappso::MsRunIdSp > ms_run_list = _p_identification_group->getMsRunIdSpList();
+        vector< MsRunSp > ms_run_list = _p_identification_group->getMsRunSpList();
         ui->sample_number_display->setText(QString("%1").arg(ms_run_list.size()));
 
         ui->group_number_display->setText(QString("%1").arg(_p_identification_group->countGroup()));
diff --git a/src/input/xpipsaxhandler.cpp b/src/input/xpipsaxhandler.cpp
index 09c5e2480..fc4057431 100644
--- a/src/input/xpipsaxhandler.cpp
+++ b/src/input/xpipsaxhandler.cpp
@@ -21,7 +21,6 @@
 ******************************************************************************/
 
 #include "xpipsaxhandler.h"
-#include <pappsomspp/msrun/msrunid.h>
 #include <pappsomspp/exception/exceptionnotfound.h>
 #include <cmath>
 #include "../utils/peptidestore.h"
@@ -181,14 +180,11 @@ bool XpipSaxHandler::startElement_modifs_mass(QXmlAttributes attributes) {
 bool XpipSaxHandler::startElement_sample(QXmlAttributes attributes) {
 
     qDebug() << "startElement_sample ";
-    pappso::MsRunId ms_run;
-    ms_run.setXmlId(attributes.value("value").simplified());
-    ms_run.setFilename(attributes.value("value").simplified());
-
-    pappso::MsRunIdSp msrunid_sp = ms_run.makeMsRunIdSp();
-    _current_identification_group_p->addMsRunIdSp(msrunid_sp);
-
-    _map_msrunid[ms_run.getXmlId()] = msrunid_sp;
+    
+    MsRunSp ms_run =  _p_project->getMsRunStore().getInstance(attributes.value("value").simplified());
+    ms_run.get()->setXmlId(attributes.value("value").simplified());
+    ms_run.get()->setFilename(attributes.value("value").simplified());
+    _current_identification_group_p->addMsRunSp(ms_run);
     qDebug() << "startElement_sample end" ;
     return true;
 }
@@ -237,8 +233,8 @@ bool XpipSaxHandler::startElement_peptide(QXmlAttributes attributes) {
 //</modifs>
     qDebug() << "startElement_peptide ";
     _current_peptide_sp = PeptideXtp(attributes.value("sequence").simplified()).makePeptideXtpSp();
-    pappso::MsRunIdSp ms_run_id = _map_msrunid[attributes.value("sample").simplified()];
-    _p_peptide_match = new PeptideMatch(ms_run_id, attributes.value("scan").simplified().toUInt());
+    MsRunSp ms_run_id =  _p_project->getMsRunStore().getInstance(attributes.value("sample").simplified());
+    _p_peptide_match = new PeptideMatch(ms_run_id.get(), attributes.value("scan").simplified().toUInt());
     _p_peptide_match->setRetentionTime(attributes.value("RT").simplified().toDouble());
     _p_peptide_match->setEvalue(attributes.value("evalue").simplified().toDouble());
     pappso::pappso_double exp_mass = attributes.value("mhplus_obser").simplified().toDouble() - pappso::MHPLUS;
diff --git a/src/input/xpipsaxhandler.h b/src/input/xpipsaxhandler.h
index f3f0ed5c9..dc172caa0 100644
--- a/src/input/xpipsaxhandler.h
+++ b/src/input/xpipsaxhandler.h
@@ -87,7 +87,6 @@ private:
     IdentificationGroup * _current_identification_group_p;
     
     QMap<QString, pappso::AaModificationP> _map_massstr_aamod;
-    QMap<QString, pappso::MsRunIdSp> _map_msrunid;
 };
 
 #endif // XTANDEMRESULTSHANDLER_H
diff --git a/src/utils/identificationdatasourcestore.h b/src/utils/identificationdatasourcestore.h
index 60b2a6c22..cfef38ee8 100644
--- a/src/utils/identificationdatasourcestore.h
+++ b/src/utils/identificationdatasourcestore.h
@@ -40,7 +40,6 @@ public:
     IdentificationDataSourceStore();
     ~IdentificationDataSourceStore();
     IdentificationDataSourceSp getInstance(const QString & location);
-    void clear();
 private :
     std::map<QString, IdentificationDataSourceSp> _map_identification_data_sources;
 };
diff --git a/src/utils/msrunstore.cpp b/src/utils/msrunstore.cpp
new file mode 100644
index 000000000..1fee9ca9e
--- /dev/null
+++ b/src/utils/msrunstore.cpp
@@ -0,0 +1,57 @@
+/**
+ * \file utils/msrunstore.cpp
+ * \date 5/4/2017
+ * \author Olivier Langella
+ * \brief store unique version of msrun references (filename, sample name...)
+ */
+
+
+/*******************************************************************************
+* 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 "msrunstore.h"
+#include <pappsomspp/exception/exceptionnotfound.h>
+
+MsRunStore::MsRunStore()
+{
+
+}
+
+MsRunStore::~MsRunStore()
+{
+
+}
+
+MsRunSp MsRunStore::getInstance(const QString & location) {
+
+    std::map< QString, MsRunSp >::iterator it = _map_msrun.find(location);
+    if (it != _map_msrun.end()) {
+        return it->second;
+    }
+    else {
+        MsRunSp p_xtfile = std::make_shared<MsRun>(location);
+        _map_msrun.insert(std::pair< QString, MsRunSp >(location, p_xtfile));
+        return p_xtfile;
+
+    }
+    throw pappso::ExceptionNotFound(QObject::tr("Ms resource %1 not found").arg(location));
+}
diff --git a/src/utils/msrunstore.h b/src/utils/msrunstore.h
new file mode 100644
index 000000000..27e6df6f2
--- /dev/null
+++ b/src/utils/msrunstore.h
@@ -0,0 +1,49 @@
+/**
+ * \file utils/msrunstore.h
+ * \date 5/4/2017
+ * \author Olivier Langella
+ * \brief store unique version of msrun references (filename, sample name...)
+ */
+
+
+/*******************************************************************************
+* 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 MSRUNSTORE_H
+#define MSRUNSTORE_H
+
+#include <QString>
+#include <map>
+#include "../core/msrun.h"
+
+class MsRunStore
+{
+public:
+    MsRunStore();
+    ~MsRunStore();
+
+    MsRunSp getInstance(const QString & location);
+private:
+    std::map<QString, MsRunSp> _map_msrun;
+};
+
+#endif // MSRUNSTORE_H
diff --git a/src/utils/readspectrum.cpp b/src/utils/readspectrum.cpp
index 0d6d8c33c..5708eb5c6 100644
--- a/src/utils/readspectrum.cpp
+++ b/src/utils/readspectrum.cpp
@@ -221,13 +221,13 @@ Spectrum readSpectrum(const QString & filename, unsigned int scan_num, unsigned
 }
 
 
-std::map<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *> create_map()
+std::map<MsRunSp, pwiz::msdata::MSDataFile *> create_map()
 {
-    std::map<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *> m;
+    std::map<MsRunSp, pwiz::msdata::MSDataFile *> m;
     return m;
 }
 
-std::map<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *> SpectrumStore::_map_msrun_msdatafile = create_map();
+std::map<MsRunSp, pwiz::msdata::MSDataFile *> SpectrumStore::_map_msrun_msdatafile = create_map();
 
 
 const QString SpectrumStore::findMzFile(const QString &filename) {
@@ -262,10 +262,10 @@ const QString SpectrumStore::findMzFile(const QString &filename) {
     return QString();
 }
 
-pappso::SpectrumSp SpectrumStore::getSpectrumSpFromMsRunIdSp(pappso::MsRunIdSp msrun, unsigned int scan_num) {
+pappso::SpectrumSp SpectrumStore::getSpectrumSpFromMsRunSp(MsRunSp msrun, unsigned int scan_num) {
     pappso::SpectrumSp spectrum;
     pwiz::msdata::MSDataFile * p_msdatafile = nullptr;
-    std::map<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *>::iterator it_msdata = _map_msrun_msdatafile.find(msrun);
+    std::map<MsRunSp, pwiz::msdata::MSDataFile *>::iterator it_msdata = _map_msrun_msdatafile.find(msrun);
     if (it_msdata == _map_msrun_msdatafile.end()) {
         //not found
 
@@ -276,7 +276,7 @@ pappso::SpectrumSp SpectrumStore::getSpectrumSpFromMsRunIdSp(pappso::MsRunIdSp m
             //return spectrum;
         }
         p_msdatafile = getPwizMSDataFile(mz_file);
-        _map_msrun_msdatafile.insert(std::pair<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *>(msrun, p_msdatafile));
+        _map_msrun_msdatafile.insert(std::pair<MsRunSp, pwiz::msdata::MSDataFile *>(msrun, p_msdatafile));
     }
     else {
         p_msdatafile =it_msdata->second;
diff --git a/src/utils/readspectrum.h b/src/utils/readspectrum.h
index 919f7bd80..89eee5bf7 100644
--- a/src/utils/readspectrum.h
+++ b/src/utils/readspectrum.h
@@ -26,9 +26,9 @@
 
 #include <QString>
 #include <pappsomspp/spectrum/spectrum.h>
-#include <pappsomspp/msrun/msrunid.h>
 #include <pwiz/data/msdata/MSDataFile.hpp>
 #include <map>
+#include "../core/msrun.h"
 
 pappso::Spectrum readSpectrum(const QString & filename, unsigned int scan_num,unsigned int & precursor_charge_state);
 
@@ -38,10 +38,10 @@ pappso::SpectrumSp getSpectrumSpFromPwizMSDataFile(pwiz::msdata::MSDataFile * p_
 
 class SpectrumStore {
 public:
-    static pappso::SpectrumSp getSpectrumSpFromMsRunIdSp(pappso::MsRunIdSp msrun, unsigned int scan_num);
+    static pappso::SpectrumSp getSpectrumSpFromMsRunSp(MsRunSp msrun, unsigned int scan_num);
 private:
     static const QString findMzFile(const QString &filename);
 private:
-    static std::map<pappso::MsRunIdSp, pwiz::msdata::MSDataFile *> _map_msrun_msdatafile;
+    static std::map<MsRunSp, pwiz::msdata::MSDataFile *> _map_msrun_msdatafile;
 };
 #endif // READSPECTRUM_H
-- 
GitLab