From 9613d0152a9784a6e0612f3ff727832ea31a346d Mon Sep 17 00:00:00 2001
From: Olivier Langella <Olivier.Langella@moulon.inra.fr>
Date: Thu, 18 May 2017 22:39:26 +0200
Subject: [PATCH] WIP: writing proticdbml

---
 src/core/peptidematch.h   |  38 +--
 src/output/proticdbml.cpp | 497 +++++++++++++++++++-------------------
 src/output/proticdbml.h   |   5 +
 src/utils/utils.cpp       |   3 +
 src/utils/utils.h         |   1 +
 5 files changed, 273 insertions(+), 271 deletions(-)

diff --git a/src/core/peptidematch.h b/src/core/peptidematch.h
index 783c73cbf..ed9680c5a 100644
--- a/src/core/peptidematch.h
+++ b/src/core/peptidematch.h
@@ -46,19 +46,19 @@ public :
      */
     pappso::pappso_double getExperimentalMass() const;
 
-        /** @brief get experimental mz of this peptide
-     * @return the real mass measured (precuror mass) by the spectrometer
-     */
+    /** @brief get experimental mz of this peptide
+    * @return the real mass measured (precuror mass) by the spectrometer
+    */
     pappso::pappso_double getExperimentalMz() const;
 
-    
+
     /** @brief set experimental mass of this peptide
      * @arg exp_mass the computed mass given the precursor measured mass and the deduced peptide charge
      */
     void setExperimentalMass(pappso::pappso_double exp_mass);
-    
-    
-        
+
+
+
     /** \brief set specific parameter value
      */
     virtual void setParam(PeptideMatchParam param, const QVariant& value);
@@ -66,14 +66,14 @@ public :
      */
     virtual const QVariant getParam(PeptideMatchParam param) const;
 
-    
-/** @brief set start position of this peptide inside the protein sequence
-     * @param start position in the protein amino acid sequence (starts at 0)
-     * */
+
+    /** @brief set start position of this peptide inside the protein sequence
+         * @param start position in the protein amino acid sequence (starts at 0)
+         * */
     void setStart(unsigned int start);
-/** @brief get start position of this peptide inside the protein sequence
-     * @return start position in the protein amino acid sequence (starts at 0)
-     * */
+    /** @brief get start position of this peptide inside the protein sequence
+         * @return start position in the protein amino acid sequence (starts at 0)
+         * */
     unsigned int getStart() const;
     void setCharge(unsigned int charge);
     void setPeptideXtpSp (PeptideXtpSp peptide);
@@ -91,19 +91,19 @@ public :
     unsigned int getCharge() const;
     const PeptideXtpSp & getPeptideXtpSp() const;
     pappso::pappso_double getEvalue() const;
-    
+
     void setGrpPeptideSp(const pappso::GrpPeptideSp & sp_grp_peptide);
     const pappso::GrpPeptideSp & getGrpPeptideSp() const;
 
-           /** @brief validate or invalidate peptides and proteins based automatic filters and manual checks
-     * */
+    /** @brief validate or invalidate peptides and proteins based automatic filters and manual checks
+    * */
     void updateAutomaticFilters(const AutomaticFilterParameters & automatic_filter_parameters);
-    
+
     /** @brief get delta between theoretical mhplus mass and mhplus experimental mass
      * theoretical mhplus mass - mhplus experimental mass
       */
     pappso::mz getDeltaMass() const;
-    
+
     ValidationState getValidationState() const;
 
 private :
diff --git a/src/output/proticdbml.cpp b/src/output/proticdbml.cpp
index 22ebf1fb7..a0b38052f 100644
--- a/src/output/proticdbml.cpp
+++ b/src/output/proticdbml.cpp
@@ -34,6 +34,7 @@
 #include <pappsomspp/amino_acid/Aa.h>
 #include "../core/msrun.h"
 #include "../config.h"
+#include "../utils/utils.h"
 
 ProticdbMl::ProticdbMl(const QString & out_filename)
 {
@@ -453,280 +454,272 @@ void ProticdbMl::writepeptideHitsbyGroup(GroupingGroup * p_group) {
     }
 }
 
-private void writeMatchs(Identification identification)
-throws MSMSException {
-    try {
-        writer.writeStartElement("matchs");
-        for (Group group : identification.getGrouping().getGroupList()) {
-            for (SubGroup sg : group.getSubGroupSet().getSubGroupList()) {
-                writer.writeStartElement("match");
-
-                // echantillons
-                Hashtable<String, String> view = new Hashtable<String, String>();
-                for (HashSampleScanSetProt hashProt : sg
-                .getHashSampleScanSetProtList()) {
-                    Match match = (Match) hashProt.getGrpProtMatch();
-                    for (MsRun sample : match.get_sample_matchs()) {
-                        if (!view.containsKey(sample.getSampleName())) {
-                            writer.writeStartElement("matchSample");
-                            writer.writeAttribute(
-                                "sample_id",
-                                ""
-                                + sample_to_id.get(sample
-                            .getSampleName()));
-                            String name = sample.getSampleName();
-                            name = name.replaceAll(".xml", "");
-                            writer.writeAttribute("name", "" + name);
-                            view.put(sample.getSampleName(), "ok");
-                            writer.writeEndElement();// "matchSample");
-                        }
-                    }
-                }
 
-                // proteins
-                int k = 1;
-                for (HashSampleScanSetProt hashProt : sg
-                        .getHashSampleScanSetProtList()) {
-                    writer.writeStartElement("proteinHit");
-                    Protein prot = (Protein) hashProt.getGrpProtMatch()
-                                   .getGrpProtein();
-                    writer.writeAttribute("sequence_id",
-                                          "" + prot_to_id.get(prot.get_description()));
-                    // proteinHit.setAttribute("score", "");
-                    writer.writeAttribute("rank", "" + k);
-
-                    // //cvparam
-                    this.writeCvParam("PROTICdbO:0000284",
-                                      "" + prot.get_mw(),
-                                      "MW determination by Benuch");
-                    /*
-                     * writer.writeStartElement("cvParam");
-                     * writer.writeAttribute("value", "" + prot.get_mw());
-                     * writer.writeAttribute("name",
-                     * "MW determination by Benuch");
-                     * writer.writeAttribute("cvLabel", "PROTICdbO");
-                     * writer.writeAttribute("accession",
-                     * "PROTICdbO:0000284"); writer.writeEndElement();//
-                     * cvParam
-                     */
-                    // evalue
-                    MsRunSet samples = ((Match) hashProt.getGrpProtMatch())
-                                       .get_sample_matchs();
-                    this.writeCvParam("PROTICdbO:0000291",
-                                      "" + prot.get_evalue(), "Xtandem log evalue");
-                    /*
-                     * writer.writeStartElement("cvParam");
-                     * writer.writeAttribute("value", "" +
-                     * prot.get_evalue());
-                     *
-                     * writer.writeAttribute("name", "Xtandem log evalue");
-                     * writer.writeAttribute("cvLabel", "PROTICdbO");
-                     * writer.writeAttribute("accession",
-                     * "PROTICdbO:0000291"); writer.writeEndElement();//
-                     * cvParam
-                     */
-
-                    // coverage
-                    if (samples.size() == 1) {
-                        this.writeCvParam(
-                            "PROTICdbO:0000285",
-                            ""
-                            + ((Match) hashProt
-                               .getGrpProtMatch())
-                            .get_coverage(),
-                            "protein coverage");
-                    }
 
-                    // [Term]
-                    // id: PROTICdbO:0000335
-                    // name: X!TandemPipeline PAI
-                    this.writeCvParam("PROTICdbO:0000335",
-                                      "" + hashProt.getPAI(), "PAI");
-
-                    // [Term]
-                    // id: PROTICdbO:0000337
-                    // name: protein group number
-                    String pappsoGroupingNumber = Utils
-                                                  .getPappsoGroupingNumber(group, sg, k);
-                    if (pappsoGroupingNumber != null) {
-                        this.writeCvParam("PROTICdbO:0000337",
-                                          pappsoGroupingNumber, "grouping number");
-                    }
+void ProticdbMl::writePeptideHit(QString xml_id, ProticPeptideHit & protic_peptide_hit) {
 
-                    writer.writeEndElement();// "proteinHit");
-                    k++;
-                }
-                for (HashSampleScanSetProt hashProt : sg
-                        .getHashSampleScanSetProtList()) {
-                    Protein prot2 = (Protein) hashProt.getGrpProtMatch()
-                                    .getGrpProtein();
-                    // peptidesHitRef
-
-                    ArrayList<Peptide> peptideList = null;
-                    if (this.xtpExperimentType.equals("phospho")) {
-                        peptideList = ((Match) hashProt.getGrpProtMatch())
-                                      .getValidPeptideInPhosphoIsland((HashSampleScanSetPhospho) hashProt);
-                    } else {
-                        peptideList = ((Match) hashProt.getGrpProtMatch())
-                                      .get_valid_peptides();
-                    }
+    // 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("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));
+    _output_stream->writeAttribute("acq_number", QString ("%1").arg(protic_peptide_hit.peptide_match->getScan()));
+    _output_stream->writeAttribute("ms_run_id", protic_peptide_hit.peptide_match->getMsRunP()->getXmlId());
+    _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(),
+                 "peptide mass id");
+    /*
+        if (xtpExperimentType.equals("phospho")) {
+            this.writeCvParam("PROTICdbO:0000349",
+                              Utils.getPappsoPhosphoPeptideMassId(group, peptideMass),
+                              "phosphopeptide mass id");
+        }
+    */
+    // pep.getMsRun().
+    IdentificationEngine identification_engine = protic_peptide_hit.peptide_match->getIdentificationDataSource()->getIdentificationEngine();
+    if (identification_engine == IdentificationEngine::XTandem) {
+        // cvparam specifique xtandem
 
-                    for (Peptide pep : peptideList) {
-                        // for (Peptide pep : ((Match)
-                        // hashProt.getGrpProtMatch())
-                        // .get_peptide_order_inclus_redon()) {
-                        String xmlId = pepSampleScanCle2xmlId.get(pep
-                                       .get_sample_scan_sequencepeptide_cle());
-                        if (xmlId == null) {
-                            String message = "the xml of peptide "
-                                             + pep.get_sample_scan_sequencepeptide_cle()
-                                             + " is not known in pepSampleScanCle2xmlId";
-                            logger.debug(message);
-                            throw new Exception(message);
-                        }
-                        writer.writeStartElement("peptideHitRef");
-                        writer.writeAttribute("peptide_hit_id", "" + xmlId);
-
-                        writer.writeStartElement("fromSeq");
-                        writer.writeAttribute(
-                            "seq_id",
-                            ""
-                            + prot_to_id.get(prot2
-                                             .get_description()));
-                        writer.writeAttribute("start", "" + pep.get_start());
-                        writer.writeAttribute("stop", "" + pep.get_stop());
-                        String res1 = pep.get_pre();
-                        res1 = res1.replaceAll("]", "-");
-                        writer.writeAttribute("residue_before_nter", ""
-                                              + res1.charAt((res1.length() - 1)));
-                        String res2 = pep.get_post();
-                        res2 = res2.replaceAll("]", "-");
-                        writer.writeAttribute("residue_after_cter", ""
-                                              + res2.charAt(0));
-
-                        writer.writeEndElement();// fromSeq
-                        writer.writeEndElement();// peptideHitRef
-                    }
+        writeCvParam("PROTICdbO:0000287", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getEvalue()),
+                     "xtandem peptide evalue");
 
-                }
-                writer.writeEndElement();// "match");
+        writeCvParam("PROTICdbO:0000288", Utils::getXmlDouble(protic_peptide_hit.peptide_match->getParam(PeptideMatchParam::tandem_hyperscore)),
+                     "xtandem peptide hyperscore");
+    }
+
+    writeCvParam("PROTICdbO:0000289",QString ("%1").arg(protic_peptide_hit.peptide_match->getRetentionTime()),
+                 "xtandem peptide retention time");
+
+    // sequences avec les modifs
+    _output_stream->writeStartElement("pepSeq");
+    _output_stream->writeStartElement("peptide");
+    _output_stream->writeCharacters(protic_peptide_hit.peptide_match->getPeptideXtpSp().get()->getSequence());
+    _output_stream->writeEndElement();// peptide
+
+    if (!protic_peptide_hit.peptide_match->getPeptideXtpSp().get()->getModifString().isEmpty()) {
+        writePtms(protic_peptide_hit.peptide_match->getPeptideXtpSp().get());
+    }
+    _output_stream->writeEndElement();// pepSeq
+    _output_stream->writeEndElement();// peptideHit
+}
+
+
+void ProticdbMl::writePtms(PeptideXtp * p_peptide) {
+    _output_stream->writeStartElement("ptms");
+    QStringList modif_list;
+    unsigned int i=1;
+    for (const pappso::Aa & amino_acid: *p_peptide) {
+        std::list<pappso::AaModificationP> aa_modif_list = amino_acid.getModificationList();
+        QStringList aamodif;
+        for (auto && aa_modif : aa_modif_list) {
+            if (!aa_modif->isInternal()) {
+                aamodif << QString::number(aa_modif->getMass(), 'f', 2);
+                _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->writeEndElement();// ptm
             }
         }
-        writer.writeEndElement();// "matchs");
-    } catch (Exception e) {
-        String message = "error writing Matchs in ProticDbMl \n"
-                         + e.getMessage();
-        logger.error(message);
-        throw new MSMSException(message);
+        i++;
     }
+
+    _output_stream->writeEndElement();// ptms
 }
 
-void ProticdbMl::writePeptideHit(Peptide pep, Group group,
-                                 PeptideMass peptideMass) throws XMLStreamException, MSMSException {
+void ProticdbMl::writeMatchs(IdentificationGroup * p_identification) {
 
-    if (peptideMass == null) {
-        String message = "peptideMass == null";
-        logger.error(message);
-        throw new MSMSException(message);
+    _output_stream->writeStartElement("matchs");
+    for (std::pair <unsigned int, GroupingGroupSp > group_pair : p_identification->getGroupStore().getGroupMap()) {
+        //for (Group group : identification.getGrouping().getGroupList()) {
+        std::vector<const ProteinMatch *> protein_match_list = group_pair.second.get()->getProteinMatchList();
+        //sort protein match by subgroup
+        std::sort(protein_match_list.begin(), protein_match_list.end(),
+                  [](const ProteinMatch * a, const ProteinMatch * b)
+        {
+            return a->getGrpProteinSp().get()->getSubGroupNumber() < b->getGrpProteinSp().get()->getSubGroupNumber();
+        });
+        
+        std::vector<const ProteinMatch *> protein_match_subgroup_list;
+        for (const ProteinMatch * p_protein_match: protein_match_list) {
+            if (protein_match_subgroup_list.size() == 0) {
+                protein_match_subgroup_list.push_back(p_protein_match);
+            }
+            else {
+                if (protein_match_subgroup_list[0]->getGrpProteinSp().get()->getSubGroupNumber() != p_protein_match->getGrpProteinSp().get()->getSubGroupNumber()) {
+                    writeMatch(protein_match_subgroup_list);
+                    protein_match_subgroup_list.clear();
+                    protein_match_subgroup_list.push_back(p_protein_match);
+                }
+                else {
+                    protein_match_subgroup_list.push_back(p_protein_match);
+                }
+            }
+        }
+        writeMatch(protein_match_subgroup_list);
     }
+    _output_stream->writeEndElement();// "matchs");
+}
 
-    String pep_hit_id = "pep" + pepSampleScanCle2xmlId.size();
-    // param par default
-    writer.writeStartElement("peptideHit");
-    writer.writeAttribute("calc_mr", "" + (pep.get_mhplus_theo() - 1.00794));
-    double exp_mz = (pep.get_mhplus_obser() + (1.00794 * (pep.getCharge() - 1)))
-    / pep.getCharge();
-    writer.writeAttribute("exp_mz", "" + exp_mz);
-    writer.writeAttribute("delta", "" + pep.get_deltamass());
-    writer.writeAttribute("exp_mr", "" + (pep.get_mhplus_obser() - 1.00794));
-    writer.writeAttribute("acq_number", "" + pep.get_scan());
-    writer.writeAttribute("ms_run_id",
-    "" + msrun_to_id.get(pep.get_sample()));
-    writer.writeAttribute("id", pep_hit_id);
-    writer.writeAttribute("exp_z", "" + pep.getCharge());
-
-    this.writeCvParam("PROTICdbO:0000339",
-    Utils.getPappsoPeptideMassId(group, peptideMass),
-    "peptide mass id");
-
-    if (xtpExperimentType.equals("phospho")) {
-        this.writeCvParam("PROTICdbO:0000349",
-        Utils.getPappsoPhosphoPeptideMassId(group, peptideMass),
-        "phosphopeptide mass id");
-    }
 
-    // pep.getMsRun().
-    IdentificationDataSource idDataSource = pep
-    .getIdentificationDataSource();
-    if (idDataSource.getClass().equals(IdentificationXtandemFile.class)) {
-        // cvparam specifique xtandem
+void ProticdbMl::writeMatch(std::vector<const ProteinMatch *> protein_match_sg_list) {
 
-        this.writeCvParam("PROTICdbO:0000287", "" + pep.get_evalue(),
-        "xtandem peptide evalue");
+            //for (SubGroup sg : group.getSubGroupSet().getSubGroupList()) {
+            _output_stream->writeStartElement("match");
 
-        this.writeCvParam("PROTICdbO:0000288", "" + pep.get_hypercorr(),
-        "xtandem peptide hyperscore");
-    }
+            // echantillons
+            Hashtable<String, String> view = new Hashtable<String, String>();
+            for (HashSampleScanSetProt hashProt : sg
+                    .getHashSampleScanSetProtList()) {
+                Match match = (Match) hashProt.getGrpProtMatch();
+                for (MsRun sample : match.get_sample_matchs()) {
+                    if (!view.containsKey(sample.getSampleName())) {
+                        writer.writeStartElement("matchSample");
+                        writer.writeAttribute(
+                            "sample_id",
+                            ""
+                            + sample_to_id.get(sample
+                                               .getSampleName()));
+                        String name = sample.getSampleName();
+                        name = name.replaceAll(".xml", "");
+                        writer.writeAttribute("name", "" + name);
+                        view.put(sample.getSampleName(), "ok");
+                        writer.writeEndElement();// "matchSample");
+                    }
+                }
+            }
 
-    this.writeCvParam("PROTICdbO:0000289",
-    "" + pep.getRetentionTimeInMinutes(),
-    "xtandem peptide retention time");
-    /*
-     * writer.writeStartElement("cvParam"); writer.writeAttribute("value",
-     * "" + pep.get_RT()); writer.writeAttribute("name",
-     * "xtandem peptide retention time"); writer.writeAttribute("cvLabel",
-     * "PROTICdbO"); writer.writeAttribute("accession",
-     * "PROTICdbO:0000289"); writer.writeEndElement();// cvParam
-     */
-
-    // Element cvParam4 = doc.createElement("cvParam");
-    // cvParam4.setAttribute("value", "" + pep.get_post());
-    // cvParam4.setAttribute("name", "xtandem peptide post");
-    // cvParam4.setAttribute("cvLabel", "PROTICdbO");
-    // cvParam4.setAttribute("accession", "PROTICdbO:00000XX");
-    // peptideHit.appendChild(cvParam4);
-    //
-    // Element cvParam5 = doc.createElement("cvParam");
-    // cvParam5.setAttribute("value", "" + pep.get_pre());
-    // cvParam5.setAttribute("name", "xtandem peptide pre");
-    // cvParam5.setAttribute("cvLabel", "PROTICdbO");
-    // cvParam5.setAttribute("accession", "PROTICdbO:00000XX");
-    // peptideHit.appendChild(cvParam5);
+            // proteins
+            int k = 1;
+            for (HashSampleScanSetProt hashProt : sg
+                    .getHashSampleScanSetProtList()) {
+                writer.writeStartElement("proteinHit");
+                Protein prot = (Protein) hashProt.getGrpProtMatch()
+                               .getGrpProtein();
+                writer.writeAttribute("sequence_id",
+                                      "" + prot_to_id.get(prot.get_description()));
+                // proteinHit.setAttribute("score", "");
+                writer.writeAttribute("rank", "" + k);
+
+                // //cvparam
+                this.writeCvParam("PROTICdbO:0000284",
+                                  "" + prot.get_mw(),
+                                  "MW determination by Benuch");
+                /*
+                 * writer.writeStartElement("cvParam");
+                 * writer.writeAttribute("value", "" + prot.get_mw());
+                 * writer.writeAttribute("name",
+                 * "MW determination by Benuch");
+                 * writer.writeAttribute("cvLabel", "PROTICdbO");
+                 * writer.writeAttribute("accession",
+                 * "PROTICdbO:0000284"); writer.writeEndElement();//
+                 * cvParam
+                 */
+                // evalue
+                MsRunSet samples = ((Match) hashProt.getGrpProtMatch())
+                                   .get_sample_matchs();
+                this.writeCvParam("PROTICdbO:0000291",
+                                  "" + prot.get_evalue(), "Xtandem log evalue");
+                /*
+                 * writer.writeStartElement("cvParam");
+                 * writer.writeAttribute("value", "" +
+                 * prot.get_evalue());
+                 *
+                 * writer.writeAttribute("name", "Xtandem log evalue");
+                 * writer.writeAttribute("cvLabel", "PROTICdbO");
+                 * writer.writeAttribute("accession",
+                 * "PROTICdbO:0000291"); writer.writeEndElement();//
+                 * cvParam
+                 */
+
+                // coverage
+                if (samples.size() == 1) {
+                    this.writeCvParam(
+                        "PROTICdbO:0000285",
+                        ""
+                        + ((Match) hashProt
+                           .getGrpProtMatch())
+                        .get_coverage(),
+                        "protein coverage");
+                }
 
-    // sequences avec les modifs
-    writer.writeStartElement("pepSeq");
-    writer.writeStartElement("peptide");
-    writer.writeCharacters("" + pep.getSequence());
-    writer.writeEndElement();// peptide
-    if (pep.get_Modifs().size() != 0) {
-        this.writePtms(pep.get_Modifs());
-    }
-    writer.writeEndElement();// pepSeq
+                // [Term]
+                // id: PROTICdbO:0000335
+                // name: X!TandemPipeline PAI
+                this.writeCvParam("PROTICdbO:0000335",
+                                  "" + hashProt.getPAI(), "PAI");
+
+                // [Term]
+                // id: PROTICdbO:0000337
+                // name: protein group number
+                String pappsoGroupingNumber = Utils
+                                              .getPappsoGroupingNumber(group, sg, k);
+                if (pappsoGroupingNumber != null) {
+                    this.writeCvParam("PROTICdbO:0000337",
+                                      pappsoGroupingNumber, "grouping number");
+                }
 
-    pepSampleScanCle2xmlId.put(pep.get_sample_scan_sequencepeptide_cle(),
-    pep_hit_id);
-    writer.writeEndElement();// peptideHit
-}
+                writer.writeEndElement();// "proteinHit");
+                k++;
+            }
+            for (HashSampleScanSetProt hashProt : sg
+                    .getHashSampleScanSetProtList()) {
+                Protein prot2 = (Protein) hashProt.getGrpProtMatch()
+                                .getGrpProtein();
+                // peptidesHitRef
+
+                ArrayList<Peptide> peptideList = null;
+                if (this.xtpExperimentType.equals("phospho")) {
+                    peptideList = ((Match) hashProt.getGrpProtMatch())
+                                  .getValidPeptideInPhosphoIsland((HashSampleScanSetPhospho) hashProt);
+                } else {
+                    peptideList = ((Match) hashProt.getGrpProtMatch())
+                                  .get_valid_peptides();
+                }
 
-private void writePtms(ArrayList<Modifs> mods) throws XMLStreamException {
-    writer.writeStartElement("ptms");
-    for (Modifs mod : mods) {
-        writer.writeStartElement("ptm");
-        writer.writeAttribute("diff_mono", "" + mod.get_modvalue());
-        writer.writeAttribute("position", "" + mod.get_posi());
-        writer.writeAttribute("aa", "" + mod.get_AA());
-        try {
-            this.writeOboModif(mod.getPsiMod());
-        } catch (MSMSException e) {
-            String message = "error writing OBO modif : " + e.getMessage();
-            logger.warn(message);
-        }
-        writer.writeEndElement();// ptm
+                for (Peptide pep : peptideList) {
+                    // for (Peptide pep : ((Match)
+                    // hashProt.getGrpProtMatch())
+                    // .get_peptide_order_inclus_redon()) {
+                    String xmlId = pepSampleScanCle2xmlId.get(pep
+                                   .get_sample_scan_sequencepeptide_cle());
+                    if (xmlId == null) {
+                        String message = "the xml of peptide "
+                                         + pep.get_sample_scan_sequencepeptide_cle()
+                                         + " is not known in pepSampleScanCle2xmlId";
+                        logger.debug(message);
+                        throw new Exception(message);
+                    }
+                    writer.writeStartElement("peptideHitRef");
+                    writer.writeAttribute("peptide_hit_id", "" + xmlId);
+
+                    writer.writeStartElement("fromSeq");
+                    writer.writeAttribute(
+                        "seq_id",
+                        ""
+                        + prot_to_id.get(prot2
+                                         .get_description()));
+                    writer.writeAttribute("start", "" + pep.get_start());
+                    writer.writeAttribute("stop", "" + pep.get_stop());
+                    String res1 = pep.get_pre();
+                    res1 = res1.replaceAll("]", "-");
+                    writer.writeAttribute("residue_before_nter", ""
+                                          + res1.charAt((res1.length() - 1)));
+                    String res2 = pep.get_post();
+                    res2 = res2.replaceAll("]", "-");
+                    writer.writeAttribute("residue_after_cter", ""
+                                          + res2.charAt(0));
+
+                    writer.writeEndElement();// fromSeq
+                    writer.writeEndElement();// peptideHitRef
+                }
 
-    }
-    writer.writeEndElement();// ptms
+            }
+            writer.writeEndElement();// "match");
 }
-
 void ProticdbMl::writeOboModif(pappso::AaModificationP mod) {
     _output_stream->writeStartElement("cvParam");
     _output_stream->writeAttribute("name", mod->getName());
diff --git a/src/output/proticdbml.h b/src/output/proticdbml.h
index 98f9ae9ce..64d82d046 100644
--- a/src/output/proticdbml.h
+++ b/src/output/proticdbml.h
@@ -38,6 +38,8 @@
 #include "../core/project.h"
 #include "../grouping/groupinggroup.h"
 
+struct ProticPeptideHit;
+
 class ProticdbMl
 {
     public:
@@ -59,6 +61,9 @@ private :
     void writeIdentificationDataSource(IdentificationDataSource * p_identification_data_source);
     void writepeptideHits(IdentificationGroup * p_identification);
     void writepeptideHitsbyGroup(GroupingGroup * p_group);
+    void writePeptideHit(QString xml_id, ProticPeptideHit & protic_peptide_hit);
+    void writePtms(PeptideXtp * p_peptide);
+    void writeMatchs(IdentificationGroup * p_identification);
     
 private :
     QFile * _output_file;
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index 9f4abcb4d..d3c583be7 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -7,6 +7,9 @@ const QUrl Utils::getOlsUrl(QString psimod_accession) {
     return url;
 }
 
+const QString Utils::getXmlDouble(pappso::pappso_double number){
+    return QString::number(number,'g',6);
+}
 
 const QString Utils::getDatabaseName(ExternalDatabase database) {
     QString database_name;
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 47e451c01..6dc65bd07 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -31,6 +31,7 @@ class Utils
 public:
     static const QUrl getOlsUrl(QString modification);
     static const QString getDatabaseName(ExternalDatabase database);
+    static const QString getXmlDouble(pappso::pappso_double number);
 };
 
 #endif // UTILS_H
-- 
GitLab