diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04a60ba1cce779b8304272a85cd230892a9044a3..520e3cb0d0dec9879a24b1595c783b9250718889 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,7 +42,7 @@ SET(SOFTWARE_NAME "XTPcpp")
 
 SET(XTPCPP_VERSION_MAJOR "0")
 SET(XTPCPP_VERSION_MINOR "1")
-SET(XTPCPP_VERSION_PATCH "8")
+SET(XTPCPP_VERSION_PATCH "9")
 SET(XTPCPP_VERSION "${XTPCPP_VERSION_MAJOR}.${XTPCPP_VERSION_MINOR}.${XTPCPP_VERSION_PATCH}")
 
 # Set the CMAKE_PREFIX_PATH for the find_library fonction when using non
diff --git a/debian/changelog b/debian/changelog
index 3c27aace1ad8a8eb3fae8b02f2a53d263cb28c30..0706dd34f47cd3812922efe2c386704adf41fd40 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xtpcpp (0.1.9-1) jessie; urgency=medium
+
+  * MGF peak sorting, waiting dialog, new ODS sheets (samples, groups)
+
+ -- Olivier Langella <Olivier.Langella@moulon.inra.fr>  Tue, 09 May 2017 11:30:23 +0200
+
 xtpcpp (0.1.8-1) jessie; urgency=medium
 
   * better peptide viewer
diff --git a/src/core/identification_sources/identificationdatasource.cpp b/src/core/identification_sources/identificationdatasource.cpp
index 0b57d64543b46286a056f9e11af0cb2cc23fc713..dcb377db87deb79a3516b3914a998070135c368c 100644
--- a/src/core/identification_sources/identificationdatasource.cpp
+++ b/src/core/identification_sources/identificationdatasource.cpp
@@ -54,8 +54,7 @@ const QString & IdentificationDataSource::getResourceName () const {
 }
 
 const QString IdentificationDataSource::getSampleName () const {
-    QFileInfo file(_ms_run_sp.get()->getFilename());
-    return file.baseName();
+    return _ms_run_sp.get()->getSampleName();
 }
 
 void IdentificationDataSource::setMsRunSp (MsRunSp ms_run_sp) {
@@ -68,6 +67,18 @@ MsRunSp IdentificationDataSource::getMsRunSp () const {
 IdentificationEngine IdentificationDataSource::getIdentificationEngine() const {
     return _engine;
 }
+const QString IdentificationDataSource::getIdentificationEngineName() const {
+    QString name = "unknown";
+    switch (_engine) {
+    case IdentificationEngine::XTandem :
+        name = "X!Tandem";
+        break;
+    case IdentificationEngine::peptider :
+        name = "peptider";
+        break;
+    }
+    return name;
+}
 const QString& IdentificationDataSource::getIdentificationEngineVersion() const {
     return _version;
 }
@@ -78,6 +89,14 @@ void IdentificationDataSource::setIdentificationEngineParam(IdentificationEngine
     _params.insert(std::pair<IdentificationEngineParam, QVariant>(param, value));
 }
 
+const QVariant IdentificationDataSource::getIdentificationEngineParam(IdentificationEngineParam param) const {
+    try {
+        return _params.at(param);
+    }
+    catch (std::out_of_range) {
+        return QVariant();
+    }
+}
 pappso::SpectrumSp IdentificationDataSource::getSpectrumSp(unsigned int scan_number) const {
     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 5f311eea6b75f66d2460541ed84a56f8de9b03c1..daf0ab5c1b834c22d4976b6336a005aaa0102a1b 100644
--- a/src/core/identification_sources/identificationdatasource.h
+++ b/src/core/identification_sources/identificationdatasource.h
@@ -44,7 +44,12 @@ public:
     ~IdentificationDataSource();
     bool operator==(const IdentificationDataSource& other) const;
 
+    /** @brief URL or filename containing identification data
+     * */
     const QString & getResourceName () const;
+    
+    /** @brief get biological sample name
+     * */
     const QString getSampleName () const;
     void setMsRunSp (MsRunSp ms_run_sp);
     MsRunSp getMsRunSp () const;
@@ -60,6 +65,10 @@ public:
     /** \brief identification engine
      */
     virtual IdentificationEngine getIdentificationEngine() const;
+
+    /** \brief identification engine name
+     */
+    const QString getIdentificationEngineName() const;
     
     /** \brief identification engine version
      */
@@ -72,6 +81,11 @@ public:
      */
     virtual void setIdentificationEngineParam(IdentificationEngineParam param, const QVariant& value);
     
+    
+    /** \brief get specific identification engine parameter value
+     */
+    virtual const QVariant getIdentificationEngineParam(IdentificationEngineParam param) const;
+    
     /** \brief add Fastafile used by the identification engine
      */
     void addFastaFile (FastaFileSp file);
diff --git a/src/core/project.cpp b/src/core/project.cpp
index 0e36c7d101b2a3745bf42aa999d8df5f345f43b1..b1390103d51c2a1b873f93b410cec4b43bd525c2 100644
--- a/src/core/project.cpp
+++ b/src/core/project.cpp
@@ -85,6 +85,9 @@ ProteinStore & Project::getProteinStore() {
 IdentificationDataSourceStore & Project::getIdentificationDataSourceStore() {
     return _identification_data_source_store;
 }
+const IdentificationDataSourceStore & Project::getIdentificationDataSourceStore() const{
+    return _identification_data_source_store;
+}
 const AutomaticFilterParameters & Project::getAutomaticFilterParameters() const {
     return _automatic_filter_parameters;
 }
diff --git a/src/core/project.h b/src/core/project.h
index c27f9cf391c1cdd9fef671ea0fb78ea921cfbc9a..32f964490892f60aa437faa67ce3a4c4c1906276 100644
--- a/src/core/project.h
+++ b/src/core/project.h
@@ -51,6 +51,7 @@ public:
     const MsRunStore & getMsRunStore() const;
     FastaFileStore & getFastaFileStore();
     IdentificationDataSourceStore & getIdentificationDataSourceStore();
+    const IdentificationDataSourceStore & getIdentificationDataSourceStore() const;
     void readXpipFile(QFileInfo xpip_source);
     IdentificationGroup* newIdentificationGroup();
 
diff --git a/src/output/ods/groupingsheet.cpp b/src/output/ods/groupingsheet.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..40cf6078cd934274cef5a91225f299598d196cc9
--- /dev/null
+++ b/src/output/ods/groupingsheet.cpp
@@ -0,0 +1,88 @@
+/**
+ * \file /output/groupingsheet.cpp
+ * \date 9/5/2017
+ * \author Olivier Langella
+ * \brief ODS grouping sheet
+ */
+
+/*******************************************************************************
+* 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 "groupingsheet.h"
+
+
+GroupingSheet::GroupingSheet (OdsExport * p_ods_export, CalcWriterInterface * p_writer, const Project * p_project): _p_project(p_project) {
+    _p_writer = p_writer;
+    _p_ods_export = p_ods_export;
+    p_writer->writeSheet("groups");
+
+
+    writeHeaders();
+
+    std::vector<IdentificationGroup *> identification_list = p_project->getIdentificationGroupList();
+    for (IdentificationGroup * p_ident:identification_list) {
+        //writeHeaders(p_ident);
+        writeIdentificationGroup(p_ident);
+    }
+}
+
+void GroupingSheet::writeIdentificationGroup(IdentificationGroup * p_ident) {
+    _p_writer->writeLine();
+    if (!_p_project->isCombineMode()) {
+        _p_writer->writeCell(p_ident->getMsRunSpList().at(0).get()->getSampleName());
+    }
+    _p_writer->writeCell((unsigned int) p_ident->countGroup());
+    _p_writer->writeCell((unsigned int) p_ident->countSubGroup());
+    _p_writer->writeCell(p_ident->countProteinMatch(ValidationState::grouped));
+    _p_writer->writeCell(p_ident->countPeptideMatch(ValidationState::grouped));
+    //_p_writer->writeCell(p_ident->countSequence(ValidationState::grouped));
+    _p_writer->writeCell(p_ident->countPeptideMassSample(ValidationState::grouped));
+    _p_writer->writeCell(p_ident->getProteinFdr(ValidationState::valid));
+    _p_writer->writeCell(p_ident->getPeptideMassFdr(ValidationState::valid));
+}
+
+
+void GroupingSheet::writeHeaders()  {
+    // groups, subgroups, proteins, psm, sequence, peptide/mass, pep FDR, prot FDR
+
+    _p_writer->writeLine();
+    if (!_p_project->isCombineMode()) {
+        _p_writer->writeCell("sample");
+    }
+    _p_writer->setCellAnnotation("number of groups");
+    _p_writer->writeCell("groups");
+    _p_writer->setCellAnnotation("number of subgroups");
+    _p_writer->writeCell("subgroups");
+    _p_writer->setCellAnnotation("number of grouped proteins");
+    _p_writer->writeCell("proteins");
+    _p_writer->setCellAnnotation("number of peptide hits : each grouped peptide spectrum match given by the identification engine");
+    _p_writer->writeCell("psm");
+    //_p_writer->writeCell("sequences");
+    _p_writer->setCellAnnotation("number of unique combinations : grouped peptide sequence+modifications+sample name");
+    _p_writer->writeCell("peptide/mass/sample");
+    _p_writer->setCellAnnotation("FDR at the protein level (number of decoy valid proteins / totale number of valid proteins)");
+    _p_writer->writeCell("prot FDR");
+    _p_writer->setCellAnnotation("FDR at the peptide level (number of decoy valid peptides / totale number of valid peptides)");
+    _p_writer->writeCell("pep FDR");
+
+
+}
diff --git a/src/output/ods/groupingsheet.h b/src/output/ods/groupingsheet.h
new file mode 100644
index 0000000000000000000000000000000000000000..d73bbc86b15a14f8bb4dc952f4c9a3150c16aee3
--- /dev/null
+++ b/src/output/ods/groupingsheet.h
@@ -0,0 +1,52 @@
+/**
+ * \file /output/groupingsheet.h
+ * \date 9/5/2017
+ * \author Olivier Langella
+ * \brief ODS grouping sheet
+ */
+
+/*******************************************************************************
+* 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 GROUPINGSHEET_H
+#define GROUPINGSHEET_H
+
+#include "../../core/project.h"
+#include <odsstream/calcwriterinterface.h>
+#include "odsexport.h"
+
+class GroupingSheet
+{
+public :
+    GroupingSheet (OdsExport * p_ods_export, CalcWriterInterface * p_writer, const Project * p_project);
+private:
+ 
+    void writeIdentificationGroup(IdentificationGroup * p_ident);
+    void writeHeaders();
+    
+private :
+    OdsExport * _p_ods_export;
+    const Project * _p_project;
+    CalcWriterInterface * _p_writer;
+};
+
+#endif // GROUPINGSHEET_H
diff --git a/src/output/ods/samplesheet.cpp b/src/output/ods/samplesheet.cpp
index f4e36b620d99e040e64c517641cf3cd087a89430..b2a4617dba1cf85f5189de81098ca07602e315b3 100644
--- a/src/output/ods/samplesheet.cpp
+++ b/src/output/ods/samplesheet.cpp
@@ -33,9 +33,51 @@ SampleSheet::SampleSheet (OdsExport * p_ods_export, CalcWriterInterface * p_writ
     _p_writer = p_writer;
     _p_ods_export = p_ods_export;
     p_writer->writeSheet("samples");
-    
-    std::vector<MsRunSp> msrun_list = _p_project->getMsRunStore().getMsRunList();
-    
-    for (MsRunSp msrun_sp: msrun_list) {
+
+    writeHeaders();
+
+    std::vector<IdentificationDataSourceSp> idrun_list = _p_project->getIdentificationDataSourceStore().getIdentificationDataSourceList();
+
+    for (IdentificationDataSourceSp idrun_sp: idrun_list) {
+        writeIdentificationDataSource(idrun_sp.get());
     }
 }
+
+void SampleSheet::writeHeaders()  {
+    // MS sample name	X!tandem xml result file name	X!Tandem version
+    //X!tandem xml model file name	total spectra used	total spectra assigned	assigned/used percent
+    //total unique assigned	database file names	MS/MS data source file name	MS/MS data source file path
+    //MS level 1	MS level 2	TIC mean in MS 1	TIC mean in MS 2	rt min	rt max
+
+
+    _p_writer->writeLine();
+    _p_writer->writeCell("sample ID");
+    _p_writer->writeCell("sample");
+    _p_writer->writeCell("MS run file");
+    _p_writer->writeCell("Identification engine");
+    _p_writer->writeCell("Identification engine version");
+    _p_writer->writeCell("Identification result file");
+    _p_writer->writeCell("Identification fasta files");
+    _p_writer->writeCell("X!Tandem parameters");
+
+
+}
+
+void SampleSheet::writeIdentificationDataSource(IdentificationDataSource * p_ident_data_source) {
+    _p_writer->writeLine();
+    _p_writer->writeCell(p_ident_data_source->getMsRunSp().get()->getXmlId());
+    _p_writer->writeCell(p_ident_data_source->getMsRunSp().get()->getSampleName());
+    _p_writer->writeCell(p_ident_data_source->getMsRunSp().get()->getFilename());
+    _p_writer->writeCell(p_ident_data_source->getIdentificationEngineName());
+    _p_writer->writeCell(p_ident_data_source->getIdentificationEngineVersion());
+    _p_writer->writeCell(p_ident_data_source->getResourceName());
+
+    QStringList fasta_files;
+    for (FastaFileSp fasta_file:p_ident_data_source->getFastaFileList()) {
+        fasta_files << fasta_file.get()->getAbsoluteFilePath();
+    }
+    _p_writer->writeCell(fasta_files.join(" "));
+
+    _p_writer->writeCell(p_ident_data_source->getIdentificationEngineParam(IdentificationEngineParam::tandem_param).toString());
+
+}
diff --git a/src/output/ods/samplesheet.h b/src/output/ods/samplesheet.h
index 6ed33b3b5b5cc24a50f4618861f86a8ebd24e998..620fab4335fd5a5d6690f03e90ed3b84c79d8619 100644
--- a/src/output/ods/samplesheet.h
+++ b/src/output/ods/samplesheet.h
@@ -39,6 +39,9 @@ class SampleSheet
 public :
     SampleSheet (OdsExport * p_ods_export, CalcWriterInterface * p_writer, const Project * p_project);
 
+private:
+    void writeHeaders();
+    void writeIdentificationDataSource(IdentificationDataSource * p_ident_data_source);
 private :
     OdsExport * _p_ods_export;
     const Project * _p_project;
diff --git a/src/utils/identificationdatasourcestore.cpp b/src/utils/identificationdatasourcestore.cpp
index 012e65c8c76a30f3cc4b1321fe31c15c14eae0a5..9c424e95ddaee071eab24391c9595c676b6707e8 100644
--- a/src/utils/identificationdatasourcestore.cpp
+++ b/src/utils/identificationdatasourcestore.cpp
@@ -63,3 +63,12 @@ qDebug() << " " << _map_identification_data_sources.size();
     }
     throw pappso::PappsoException(QObject::tr("Identification resource %1 not recognized").arg(location));
 }
+
+
+std::vector<IdentificationDataSourceSp> IdentificationDataSourceStore::getIdentificationDataSourceList() const {
+    std::vector<IdentificationDataSourceSp> idsource_list;
+    for (auto & msrun_pair :_map_identification_data_sources) {
+        idsource_list.push_back(msrun_pair.second);
+    }
+    return idsource_list;
+}
diff --git a/src/utils/identificationdatasourcestore.h b/src/utils/identificationdatasourcestore.h
index e634800fb964e3c4ffe9e30a7ef340ecf101583c..a2e204f34c58d32faa5d7e52ebb60b0ea71c2bcb 100644
--- a/src/utils/identificationdatasourcestore.h
+++ b/src/utils/identificationdatasourcestore.h
@@ -42,6 +42,8 @@ public:
     IdentificationDataSourceStore();
     ~IdentificationDataSourceStore();
     IdentificationDataSourceSp getInstance(const QString & location);
+    
+    std::vector<IdentificationDataSourceSp> getIdentificationDataSourceList() const;
 private :
     std::map<QString, IdentificationDataSourceSp> _map_identification_data_sources;
 };