diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 87fc13db88a4dd7ff4d9dee2c6318576569066b8..b406d160ae69f0033245f0f75fe8c068b0a095fa 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -70,6 +70,7 @@ SET(CPP_FILES
   input/xpipsaxhandler.cpp
   input/xtandemsaxhandler.cpp
   output/masschroqml.cpp
+  output/proticdbml.cpp
   output/ods/comparbasesheet.cpp
   output/ods/comparspecificspectrasheet.cpp
   output/ods/comparspectrasheet.cpp
diff --git a/src/core/peptidematch.cpp b/src/core/peptidematch.cpp
index 77c4a5df5c1faa8f97e1354603c6c124452d9826..95aa807dc6c06e1dc53dee67a16c3031d039c683 100644
--- a/src/core/peptidematch.cpp
+++ b/src/core/peptidematch.cpp
@@ -93,6 +93,9 @@ pappso::mz PeptideMatch::getDeltaMass() const {
 unsigned int PeptideMatch::getStart() const {
     return _start;
 }
+unsigned int PeptideMatch::getStop() const {
+    return _start+_peptide_sp.get()->size();
+}
 void PeptideMatch::setCharge(unsigned int charge) {
     _charge =charge;
 }
diff --git a/src/core/peptidematch.h b/src/core/peptidematch.h
index ed9680c5accdc2006ebec6eca2e1e766a3c23d73..69bbe3efb0aa69a01d1ea72ba6ced5bff615657c 100644
--- a/src/core/peptidematch.h
+++ b/src/core/peptidematch.h
@@ -75,6 +75,10 @@ public :
          * @return start position in the protein amino acid sequence (starts at 0)
          * */
     unsigned int getStart() const;
+    /** @brief get stop position of this peptide inside the protein sequence
+         * @return stop position in the protein amino acid sequence (starts at 0)
+         * */
+    unsigned int getStop() const;
     void setCharge(unsigned int charge);
     void setPeptideXtpSp (PeptideXtpSp peptide);
     void setIdentificationDataSource(IdentificationDataSource* identification_source);
diff --git a/src/core/proteinmatch.cpp b/src/core/proteinmatch.cpp
index 5da4dfbf486072547fdc6dc3503df3ea61e02c97..ca7b1f7e7d89da77244222e78ff4deb3125d4962 100644
--- a/src/core/proteinmatch.cpp
+++ b/src/core/proteinmatch.cpp
@@ -189,7 +189,7 @@ std::vector<PeptideMatch *> ProteinMatch::getPeptideMatchList(ValidationState st
     std::vector<PeptideMatch *> peptide_match_list;
     for (auto & p_peptide_match : _peptide_match_list) {
         if (p_peptide_match->getValidationState() >= state) {
-            ProteinMatch.push_back(p_peptide_match);
+            peptide_match_list.push_back(p_peptide_match);
         }
     }
     return peptide_match_list;
diff --git a/src/gui/main.ui b/src/gui/main.ui
index 8a765a4af60b36e030cb2a968a19acca1f5230e7..088de361826b74d5c7b0ce9343c9cecd4c58590c 100644
--- a/src/gui/main.ui
+++ b/src/gui/main.ui
@@ -26,7 +26,7 @@
      <x>0</x>
      <y>0</y>
      <width>463</width>
-     <height>25</height>
+     <height>23</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -40,6 +40,7 @@
      <addaction name="actionFasta"/>
      <addaction name="actionMassChroQ"/>
      <addaction name="actionSpreadsheet"/>
+     <addaction name="actionProticDb"/>
     </widget>
     <addaction name="actionLoad_results"/>
     <addaction name="actionLoad"/>
@@ -102,6 +103,11 @@
     <string>&amp;Labeling methods</string>
    </property>
   </action>
+  <action name="actionProticDb">
+   <property name="text">
+    <string>PROTICdb</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="../xtpcpp.qrc"/>
@@ -235,11 +241,28 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>actionProticDb</sender>
+   <signal>triggered()</signal>
+   <receiver>Main</receiver>
+   <slot>doActionProticDb()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>231</x>
+     <y>191</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>selectXpipFile()</slot>
   <slot>loadResults()</slot>
   <slot>doActionMassChroQ()</slot>
+  <slot>doActionProticDb()</slot>
   <slot>doActionSpreadsheet()</slot>
   <slot>doActionQuit()</slot>
   <slot>doActionModifications()</slot>
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index a4c74bee8669103e8025f4f77da1b2397ba2caeb..c2568e55810b101f7a1466180d7389761ea22899 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -325,7 +325,7 @@ void MainWindow::doActionMassChroQ() {
 
         settings.setValue("path/mcqfile", QFileInfo(filename).absolutePath());
         
-        showWaitingMessage(tr("Loading %1 XPIP file").arg(QFileInfo(filename).fileName()));
+        showWaitingMessage(tr("Writing %1 XPIP file").arg(QFileInfo(filename).fileName()));
         emit operateWritingMassChroqFile(filename, _project_sp);
         //emit operateXpipFile(filename);
     }
@@ -334,3 +334,31 @@ void MainWindow::doActionMassChroQ() {
     }
     qDebug() << "MainWindow::doActionMassChroQ end";
 }
+
+void MainWindow::doActionProticDb() {
+    qDebug() << "MainWindow::doActionProticDb begin";
+    try {
+        _project_sp.get()->checkPsimodCompliance();
+
+        QSettings settings;
+        QString default_location = settings.value("path/proticfile", "").toString();
+
+        QString filename = QFileDialog::getSaveFileName(this, tr("Save PROTICdbML file"),
+                           QString("%1/untitled.proticdbml").arg(default_location),
+                           tr("PROTICdbML (*.proticdbml)"));
+
+        if (filename.isEmpty()) {
+            return;
+        }
+
+        settings.setValue("path/proticfile", QFileInfo(filename).absolutePath());
+        
+        showWaitingMessage(tr("Writing %1 PROTICdbML file").arg(QFileInfo(filename).fileName()));
+        emit operateWritingProticFile(filename, _project_sp);
+        //emit operateXpipFile(filename);
+    }
+    catch (pappso::PappsoException & error) {
+        viewError(tr("Error while writing PROTICdbML file :\n%1").arg(error.qwhat()));
+    }
+    qDebug() << "MainWindow::doActionProticDb end";
+}
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index 3f72f27b42e8284150baf050b9e8bbcf576e020e..956d8cf372c1c49a85ddbb647a4f42b9a33c15f5 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -59,6 +59,7 @@ public slots:
     void doActionQuit();
     void doActionFasta();
     void doActionMassChroQ();
+    void doActionProticDb();
     void doActionLabelingMethods();
     void doActionSpreadsheet();
     void doActionModifications();
@@ -79,6 +80,7 @@ signals:
     void operateLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list);
     void operateWritingOdsFile(QString filename, ProjectSp project_sp);
     void operateWritingMassChroqFile(QString filename, ProjectSp project_sp);
+    void operateWritingProticFile(QString filename, ProjectSp project_sp);
     void operateGrouping(ProjectSp project_sp);
 
 protected:
diff --git a/src/gui/workerthread.cpp b/src/gui/workerthread.cpp
index 6e97c8c9cfd36bf30b094c6fbaff21c062a5dfba..083e52e0d8171f6064d0d9327c0941139c067942 100644
--- a/src/gui/workerthread.cpp
+++ b/src/gui/workerthread.cpp
@@ -32,6 +32,7 @@
 #include <pappsomspp/pappsoexception.h>
 #include <QDebug>
 #include "../output/masschroqml.h"
+#include "../output/proticdbml.h"
 #include "../output/ods/odsexport.h"
 #include "files/xpipfile.h"
 #include "mainwindow.h"
@@ -62,6 +63,8 @@ WorkerThread::WorkerThread(MainWindow * p_main_window)
     connect(this, SIGNAL(groupingFinished()), p_main_window,SLOT(doGroupingFinished()));
     //masschroq write
     connect(p_main_window, SIGNAL(operateWritingMassChroqFile(QString, ProjectSp)), this,SLOT(doWritingMassChroqFile(QString, ProjectSp)));
+    //protic write
+    connect(p_main_window, SIGNAL(operateWritingProticFile(QString,ProjectSp)), this,SLOT(doWritingProticFile(QString,ProjectSp)));
     //writing ODS file :
     connect(p_main_window, SIGNAL(operateWritingOdsFile(QString, ProjectSp)), this,SLOT(doWritingOdsFile(QString, ProjectSp)));
     connect(this, SIGNAL(operationFailed(QString)), p_main_window,SLOT(doOperationFailed(QString)));
@@ -200,6 +203,20 @@ void WorkerThread::doWritingMassChroqFile(QString filename, ProjectSp project_sp
     }
 }
 
+void WorkerThread::doWritingProticFile(QString filename, ProjectSp project_sp) {
+
+    try {
+        emit loadingMessage(tr("writing PROTICdbML file, please wait"));
+        ProticdbMl output(filename);
+        output.write(project_sp);
+        output.close();
+        emit operationFinished();
+    }
+    catch (pappso::PappsoException & error) {
+        emit operationFailed(tr("Error while writing PROTICdbML file :\n%1").arg(error.qwhat()));
+    }
+}
+
 void WorkerThread::doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list) {
 
     qDebug() << "WorkerThread::doLoadingResults begin ";
diff --git a/src/gui/workerthread.h b/src/gui/workerthread.h
index 76af2b83a59469f8404dde1311b5cd81795690e9..6cf0c3c9e3d0335b2b88f5ecd3c306a6dc2a431b 100644
--- a/src/gui/workerthread.h
+++ b/src/gui/workerthread.h
@@ -58,6 +58,7 @@ public slots:
     void doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list);
     void doWritingOdsFile(QString filename, ProjectSp project_sp);
     void doWritingMassChroqFile(QString filename, ProjectSp project_sp);
+    void doWritingProticFile(QString filename, ProjectSp project_sp);
     void doGrouping(ProjectSp project_sp);
     void doGroupingOnIdentification(IdentificationGroup * p_identification_group, GroupingType grouping_type);
 
diff --git a/src/output/proticdbml.cpp b/src/output/proticdbml.cpp
index 0e41c92d5c281442f86b88cf2e04d891524860f0..30ce13725d8c9aeacd40d41abe512b355fad43a5 100644
--- a/src/output/proticdbml.cpp
+++ b/src/output/proticdbml.cpp
@@ -127,10 +127,8 @@ void ProticdbMl::writeSequence(ProteinMatch * p_protein_match) {
         // dbname="AGI_LocusCode"></dbxref>
         //if (prot.get_dbxref_type().equals("no") == false) {
         for (const std::pair<ExternalDatabase, QString> & dbxref :p_protein_match->getProteinXtpSp().get()->getDbxrefList()) {
-            //if (false) {
             _output_stream->writeStartElement("dbxref");
-            _output_stream->writeAttribute("dbname",
-                                           Utils::getDatabaseName (dbxref.first));
+            _output_stream->writeAttribute("dbname", Utils::getDatabaseName(dbxref.first));
             _output_stream->writeAttribute("key",
                                            dbxref.second);
             _output_stream->writeEndElement();// dbxref
@@ -180,7 +178,7 @@ void ProticdbMl::writeProject() {
     _output_stream->writeEndDocument();
 
 
-    qDebug() << "ProticdbMl::writeProject end duration = " << duracel << "ms";
+    qDebug() << "ProticdbMl::writeProject end duration = " << _duracel << "ms";
 }
 
 void ProticdbMl::writeIdentMethod() {
@@ -201,9 +199,9 @@ void ProticdbMl::writeIdentMethod() {
 
 void ProticdbMl::writeSamples() {
     _output_stream->writeStartElement("samples");
-    for (std::vector<MsRunSp> msrun_sp : _sp_project.get()->getMsRunStore().getMsRunList()) {
+    for (MsRunSp msrun_sp : _sp_project.get()->getMsRunStore().getMsRunList()) {
         _output_stream->writeStartElement("sample");
-        QString id_samp = "samp" + pappso::Utils::getLexicalOrderedString(sample_to_id.size());
+        QString id_samp = "samp" + pappso::Utils::getLexicalOrderedString(_sample_to_id.size());
         QString id_msrun = msrun_sp.get()->getXmlId();
         QString name = msrun_sp.get()->getSampleName();
         // balise sample
@@ -225,7 +223,7 @@ void ProticdbMl::writeSamples() {
 void ProticdbMl::writeMsRuns() {
 
     _output_stream->writeStartElement("msRuns");
-    for (std::vector<MsRunSp> msrun_sp : _sp_project.get()->getMsRunStore().getMsRunList()) {
+    for (MsRunSp msrun_sp : _sp_project.get()->getMsRunStore().getMsRunList()) {
 
         QString name = msrun_sp.get()->getSampleName();
 
@@ -415,12 +413,12 @@ void ProticdbMl::writeIdentificationRun(IdentificationGroup * p_identification)
 void ProticdbMl::writepeptideHits(IdentificationGroup * p_identification) {
     _output_stream->writeStartElement("peptideHits");
     for (std::pair <unsigned int, GroupingGroupSp > group_pair : p_identification->getGroupStore().getGroupMap()) {
-        writepeptideHitsbyGroup(group_pair.second);
+        writepeptideHitsbyGroup(group_pair.second.get());
     }
     _output_stream->writeEndElement();// "peptideHits");
 }
 
-QString getProticPeptideHitKey(PeptideMatch * p_peptide_match) {
+QString getProticPeptideHitKey(const PeptideMatch * p_peptide_match) {
     return (QString ("%1 %2 %3").arg(p_peptide_match->getHashSampleScan()).arg(p_peptide_match->getPeptideXtpSp().get()->toAbsoluteString()).arg(p_peptide_match->getIdentificationDataSource()->getResourceName()));
 }
 
@@ -431,15 +429,16 @@ struct ProticPeptideHit {
     /** key = getProticPeptideHitKey
      * */
     QString key;
-    PeptideMatch * peptide_match;
+    const PeptideMatch * peptide_match;
 };
 
 void ProticdbMl::writepeptideHitsbyGroup(GroupingGroup * p_group) {
 
     std::vector <ProticPeptideHit> protic_peptide_hit_list;
 
-    for  (PeptideMatch* p_peptide_match : p_group->getPeptideMatchList()) {
-        protic_peptide_hit_list.push_back(ProticPeptideHit(getProticPeptideHitKey(p_peptide_match), p_peptide_match));
+    for  (const PeptideMatch* p_peptide_match : p_group->getPeptideMatchList()) {
+        ProticPeptideHit protic_peptide_hit = {getProticPeptideHitKey(p_peptide_match), p_peptide_match};
+        protic_peptide_hit_list.push_back(protic_peptide_hit);
     }
     std::sort(protic_peptide_hit_list.begin(),protic_peptide_hit_list.end(),[](const ProticPeptideHit & first, const ProticPeptideHit & second) {
         return (first.key < second.key) ;
@@ -460,7 +459,7 @@ void ProticdbMl::writePeptideHit(QString xml_id, ProticPeptideHit & protic_pepti
 
     // param par default
     _output_stream->writeStartElement("peptideHit");
-    _output_stream->writeAttribute("calc_mr", Utils::getXmlDouble(protic_peptide_hit.peptide_match->setPeptideXtpSp().get()->getMass()));
+    _output_stream->writeAttribute("calc_mr", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getPeptideXtpSp().get()->getMass()));
     _output_stream->writeAttribute("exp_mz", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getExperimentalMz()));
     _output_stream->writeAttribute("delta", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getDeltaMass()));
     _output_stream->writeAttribute("exp_mr", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getExperimentalMz()- pappso::MHPLUS));
@@ -469,7 +468,7 @@ void ProticdbMl::writePeptideHit(QString xml_id, ProticPeptideHit & protic_pepti
     _output_stream->writeAttribute("id", xml_id);
     _output_stream->writeAttribute("exp_z", QString ("%1").arg(protic_peptide_hit.peptide_match->getCharge()));
 
-    writeCvParam("PROTICdbO:0000339",protic_peptide_hit.peptide_match->setGrpPeptideSp().get()->getGroupingId(),
+    writeCvParam("PROTICdbO:0000339",protic_peptide_hit.peptide_match->getGrpPeptideSp().get()->getGroupingId(),
                  "peptide mass id");
     /*
         if (xtpExperimentType.equals("phospho")) {
@@ -486,7 +485,7 @@ void ProticdbMl::writePeptideHit(QString xml_id, ProticPeptideHit & protic_pepti
         writeCvParam("PROTICdbO:0000287", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getEvalue()),
                      "xtandem peptide evalue");
 
-        writeCvParam("PROTICdbO:0000288", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getParam(PeptideMatchParam::tandem_hyperscore)),
+        writeCvParam("PROTICdbO:0000288", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getParam(PeptideMatchParam::tandem_hyperscore).toDouble()),
                      "xtandem peptide hyperscore");
     }
 
@@ -520,7 +519,7 @@ void ProticdbMl::writePtms(PeptideXtp * p_peptide) {
                 _output_stream->writeStartElement("ptm");
                 _output_stream->writeAttribute("diff_mono", Utils::getXmlDouble(aa_modif->getMass()));
                 _output_stream->writeAttribute("position", QString ("%1").arg(i));
-                _output_stream->writeAttribute("aa", amino_acid.getLetter());
+                _output_stream->writeAttribute("aa", QString(amino_acid.getLetter()));
                 _output_stream->writeEndElement();// ptm
             }
         }
@@ -600,19 +599,19 @@ void ProticdbMl::writeMatch(std::vector<const ProteinMatch *> & protein_match_sg
                      , "Xtandem log evalue");
 
         // coverage
-        this.writeCvParam(
+        writeCvParam(
             "PROTICdbO:0000285", Utils::getXmlDouble(p_protein_match->getCoverage()),
             "protein coverage");
 
         // [Term]
         // id: PROTICdbO:0000335
         // name: X!TandemPipeline PAI
-        this.writeCvParam("PROTICdbO:0000335",Utils::getXmlDouble(p_protein_match->getPAI()), "PAI");
+        writeCvParam("PROTICdbO:0000335",Utils::getXmlDouble(p_protein_match->getPAI()), "PAI");
 
         // [Term]
         // id: PROTICdbO:0000337
         // name: protein group number
-        this.writeCvParam("PROTICdbO:0000337",QString("%1").arg(p_protein_match->getGroupingGroupSp().get()->getGroupNumber()), "grouping number");
+        writeCvParam("PROTICdbO:0000337",QString("%1").arg(p_protein_match->getGroupingGroupSp().get()->getGroupNumber()), "grouping number");
 
         _output_stream->writeEndElement();// "proteinHit");
     }
@@ -634,14 +633,14 @@ void ProticdbMl::writeMatch(std::vector<const ProteinMatch *> & protein_match_sg
             _output_stream->writeAttribute("stop", QString("%1").arg(p_peptide_match->getStop()+1));
             QString residue_before_nter = "-";
             if (p_peptide_match->getStart() > 0) {
-                residue_before_nter = p_protein_match->getProteinXtpSp().get()->getSequence().mid(QString("%1").arg(p_peptide_match->getStart()-1,1);
+                residue_before_nter = p_protein_match->getProteinXtpSp().get()->getSequence().mid(p_peptide_match->getStart()-1,1);
             }
-                                  _output_stream->writeAttribute("residue_before_nter", residue_before_nter);
+            _output_stream->writeAttribute("residue_before_nter", residue_before_nter);
             QString residue_after_cter = "-";
             if (p_peptide_match->getStop() < (p_protein_match->getProteinXtpSp().get()->getSequence().size()-1)) {
-                residue_before_nter = p_protein_match->getProteinXtpSp().get()->getSequence().mid(QString("%1").arg(p_peptide_match->getStop()-1,1);
+                residue_before_nter = p_protein_match->getProteinXtpSp().get()->getSequence().mid(p_peptide_match->getStop(),1);
             }
-                                  _output_stream->writeAttribute("residue_after_cter", residue_after_cter);
+            _output_stream->writeAttribute("residue_after_cter", residue_after_cter);
 
             _output_stream->writeEndElement();// fromSeq
             _output_stream->writeEndElement();// peptideHitRef
@@ -672,3 +671,4 @@ void ProticdbMl::writeCvParam(QString acc, QString value, QString description) {
     _output_stream->writeEndElement();// cvParam
 
 }
+
diff --git a/src/output/proticdbml.h b/src/output/proticdbml.h
index 36475e6121daf1c80b3340f18aa9e1fbdc910b81..65f6bbb06159dab8bdb8747ba58549d3de6a389c 100644
--- a/src/output/proticdbml.h
+++ b/src/output/proticdbml.h
@@ -64,7 +64,7 @@ private :
     void writePeptideHit(QString xml_id, ProticPeptideHit & protic_peptide_hit);
     void writePtms(PeptideXtp * p_peptide);
     void writeMatchs(IdentificationGroup * p_identification);
-    void writeMatch(GroupingGroup * p_group,std::vector<const ProteinMatch *> & protein_match_sg_list);
+    void writeMatch(std::vector<const ProteinMatch *> & protein_match_sg_list);
     
 private :
     QFile * _output_file;
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 6dc65bd075e39e978c506cf8c878acfcd6e0d772..5b5581f0f00a80c12223f29e355e2b714447b215 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -23,9 +23,10 @@
 #include<QUrl>
 #include <QString>
 #include "types.h"
+#include <pappsomspp/types.h>
 
-#ifndef UTILS_H
-#define UTILS_H
+#ifndef XTPUTILS_H
+#define XTPUTILS_H
 class Utils
 {
 public:
@@ -34,4 +35,4 @@ public:
     static const QString getXmlDouble(pappso::pappso_double number);
 };
 
-#endif // UTILS_H
+#endif // XTPUTILS_H