/**
 * \file src/input/tandem/tandemreader.cpp
 * \date 29/8/2022
 * \author Olivier Langella
 * \brief new method to read X!Tandem XML files
 */


/*******************************************************************************
 * Copyright (c) 2022 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.fr>.
 *
 * This file is part of i2MassChroQ.
 *
 *     i2MassChroQ 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.
 *
 *     i2MassChroQ 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 i2MassChroQ.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/


#include <pappsomspp/core/utils.h>
#include <pappsomspp/core/exception/exceptionnotfound.h>
#include <pappsomspp/core/exception/exceptioninterrupted.h>
#include "../../utils/utils.h"
#include "tandemreader.h"

TandemReader::TandemReader(
  pappso::UiMonitorInterface *p_monitor,
  Project *p_project,
  IdentificationGroup *p_identification_group,
  IdentificationXtandemFile *p_identification_data_source,
  std::map<pappso::Enums::AminoAcidChar, pappso::AaModificationP>
    residue_modifications)
{
  mp_monitor                   = p_monitor;
  mp_project                   = p_project;
  mp_identificationGroup       = p_identification_group;
  mp_identificationDataSource  = p_identification_data_source;
  msp_msrun                    = p_identification_data_source->getMsRunSp();
  m_residueMassModificationMap = residue_modifications;
}

TandemReader::~TandemReader()
{
}

void
TandemReader::readStream()
{
  // mp_monitor->setStatus("reading X!Tandem result file");
  if(m_qxmlStreamReader.readNextStartElement())
    {
      if(m_qxmlStreamReader.name().toString() == "bioml")
        {

          std::size_t count = 0;
          while(readGroup())
            {
              if((count % 1000) == 0)
                {
                  if(mp_monitor->shouldIstop())
                    {
                      throw pappso::ExceptionInterrupted(QObject::tr(
                        "X!Tandem file reading interrupted by the user"));
                    }
                }
              count++;
            }
        }
      else
        {
          m_qxmlStreamReader.raiseError(
            QObject::tr("Not an X!Tandem input file (no bioml)"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

bool
TandemReader::readGroup()
{
  TandemGroup tandem_group;
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "group")
        {
          // logger.debug("startElementgroup begin");
          // <group label="performance parameters" type="parameters">
          tandem_group.label =
            m_qxmlStreamReader.attributes().value("label").toString();
          tandem_group.type =
            m_qxmlStreamReader.attributes().value("type").toString();

          //<group label="residue mass parameters"
          // type="parameters">
          if(tandem_group.label == "residue mass parameters")
            {
              m_qxmlStreamReader.skipCurrentElement();
            }
          else
            {
              if(tandem_group.type == "model")
                {
                  mp_monitor->count();
                  tandem_group.scan =
                    m_qxmlStreamReader.attributes().value("id").toUInt();
                  tandem_group.mhplusObser =
                    m_qxmlStreamReader.attributes().value("mh").toDouble();
                  tandem_group.charge =
                    m_qxmlStreamReader.attributes().value("z").toUInt();
                  tandem_group.retentionTime = m_qxmlStreamReader.attributes()
                                                 .value("rt")
                                                 .toString()
                                                 .replace("PT", "")
                                                 .replace("S", "")
                                                 .toDouble();
                  while(m_qxmlStreamReader.readNextStartElement())
                    {
                      qDebug() << m_qxmlStreamReader.name();
                      if(m_qxmlStreamReader.name().toString() == "group")
                        {
                          m_qxmlStreamReader.skipCurrentElement();
                        }
                      else if(m_qxmlStreamReader.name().toString() == "protein")
                        {
                          while(m_qxmlStreamReader.readNextStartElement())
                            {
                              qDebug() << m_qxmlStreamReader.name();
                              if((m_qxmlStreamReader.name().toString() ==
                                  "note") &&
                                 (m_qxmlStreamReader.attributes()
                                    .value("label")
                                    .toString() == "description"))
                                {

                                  //<note label="description">GRMZM2G083841_P01
                                  // P04711 Phosphoenolpyruvate
                                  // carboxylase 1 (PEPCase 1)(PEPC 1)(EC
                                  // //4.1.1.31) seq=translation;
                                  // coord=9:61296279..61301686:1;
                                  // parent_transcript=GRMZM2G083841_T01;
                                  ////parent_gene=GRMZM2G083841</note>
                                  //_p_protein_match->getProteinXtpSp().get()->setDescription(_current_text.section("
                                  //",1));
                                  tandem_group.protein.setCompleteDescription(
                                    m_qxmlStreamReader.readElementText());
                                  if(!tandem_group.protein.getAccession()
                                        .endsWith(":reversed") &&
                                     tandem_group.protein.getDescription()
                                       .endsWith(":reversed"))
                                    {
                                      // to fit most cases, just check that the
                                      // :reversed chars added by X!Tandem are
                                      // not in the description. if so, then add
                                      // it too in the accession
                                      tandem_group.protein.setAccession(
                                        QString("%1%2")
                                          .arg(
                                            tandem_group.protein.getAccession())
                                          .arg(":reversed"));
                                    }
                                  // for older versions < 2013.09.01.1
                                  if(!tandem_group.protein.getAccession()
                                        .endsWith("|reversed") &&
                                     tandem_group.protein.getDescription()
                                       .endsWith("|reversed"))
                                    {
                                      // to fit most cases, just check that the
                                      // :reversed chars added by X!Tandem are
                                      // not in the description. if so, then add
                                      // it too in the accession
                                      tandem_group.protein.setAccession(
                                        QString("%1%2")
                                          .arg(
                                            tandem_group.protein.getAccession())
                                          .arg("|reversed"));
                                    }

                                  // qDebug() << "startElement_protein
                                  // accession" << accession;
                                  tandem_group.p_proteinMatch =
                                    mp_identificationGroup
                                      ->getProteinMatchInstance(
                                        tandem_group.protein.getAccession());

                                  tandem_group.p_proteinMatch->setChecked(
                                    false);
                                  // qDebug() << "startElement_protein
                                  // p_protein_match 3 " << _p_protein_match;
                                  ProteinXtpSp sp_xtp_protein =
                                    tandem_group.protein.makeProteinXtpSp();
                                  tandem_group.p_proteinMatch->setProteinXtpSp(
                                    mp_project->getProteinStore().getInstance(
                                      sp_xtp_protein));
                                  tandem_group.p_proteinMatch->setChecked(true);
                                }
                              else if((m_qxmlStreamReader.name().toString() ==
                                       "file") &&
                                      (m_qxmlStreamReader.attributes()
                                         .value("type")
                                         .toString() == "peptide"))
                                {
                                  //<file type="peptide"
                                  // URL="/gorgone/pappso/formation/2018novembre/shotgun/database/Genome_Z_mays_5a.fasta"/>

                                  // prot_.setDatabase(identification_.getDatabaseSet().getInstance(
                                  //                     attrs.getValue("URL")));
                                  if(tandem_group.p_proteinMatch == nullptr)
                                    {
                                      throw pappso::PappsoException(
                                        "ERROR in "
                                        "XtandemSaxHandler::startElement_file "
                                        ": _p_protein_match == nullptr");
                                    }
                                  tandem_group.p_proteinMatch->getProteinXtpSp()
                                    .get()
                                    ->setFastaFileP(
                                      mp_project->getFastaFileStore()
                                        .getInstance(FastaFile(
                                          m_qxmlStreamReader.attributes()
                                            .value("URL")
                                            .toString()))
                                        .get());
                                  m_qxmlStreamReader.skipCurrentElement();
                                }
                              else if(m_qxmlStreamReader.name().toString() ==
                                      "peptide")
                                {

                                  QString protein_sequence;
                                  while(m_qxmlStreamReader.readNext() ==
                                        QXmlStreamReader::TokenType::Characters)
                                    {
                                      qDebug() << m_qxmlStreamReader.text();
                                      protein_sequence +=
                                        m_qxmlStreamReader.text();
                                    }
                                  protein_sequence =
                                    protein_sequence.simplified().replace(" ",
                                                                          "");
                                  qDebug() << protein_sequence;
                                  if(!protein_sequence.isEmpty())
                                    {
                                      //._sequence.replace(QRegExp("\\*"),
                                      //"")).removeTranslationStop()
                                      //_p_protein_match->getProteinXtpSp().get()->setSequence(_current_text.replace(QRegExp("\\*"),
                                      //""));
                                      if(tandem_group.p_proteinMatch == nullptr)
                                        {
                                          throw pappso::PappsoException(
                                            "ERROR in "
                                            "XtandemSaxHandler::startElement_"
                                            "domain : _p_protein_match == "
                                            "nullptr");
                                        }

                                      tandem_group.p_proteinMatch
                                        ->getProteinXtpSp()
                                        .get()
                                        ->setSequence(protein_sequence);
                                    }
                                  readDomain(tandem_group);
                                  while(
                                    m_qxmlStreamReader.readNextStartElement())
                                    {
                                      readDomain(tandem_group);
                                    }
                                }
                              else
                                {
                                  m_qxmlStreamReader.raiseError(QObject::tr(
                                    "Not an X!Tandem input file (no bioml)"));
                                  m_qxmlStreamReader.skipCurrentElement();
                                }
                            }
                        }
                      else
                        {
                          m_qxmlStreamReader.raiseError(QObject::tr(
                            "Not an X!Tandem input file (no bioml)"));
                          m_qxmlStreamReader.skipCurrentElement();
                        }
                    }

                  // m_qxmlStreamReader.skipCurrentElement();
                }
              else if(tandem_group.type == "parameters")
                {

                  readGroupTypeParameters(tandem_group);
                }
              else
                {
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an X!Tandem input file (no bioml)"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }

      else
        {
          m_qxmlStreamReader.raiseError(
            QObject::tr("Not an X!Tandem input file (no bioml)"));
          m_qxmlStreamReader.skipCurrentElement();
        }

      return true;
    }
  return false;
}

void
TandemReader::readDomain(TandemReader::TandemGroup &tandem_group)
{
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "domain")
    {

      // mh="1120.529471"
      //<domain id="1976.1.1" start="620"
      // end="629" expect="9.7e-04"
      // mh="1120.5307"
      // delta="-0.0012" hyperscore="29.9"
      // nextscore="10.2" y_score="10.4"
      // y_ions="7"
      // b_score="11.2" b_ions="3" pre="QLYR"
      // post="RYGV"  seq="AQEEMAQVAK"
      // missed_cleavages="0">  qDebug() <<
      // "startElement_domain ";

      // <domain id="4017.1.1" start="21"
      // end="31" expect="2.0e-06" mh="1263.575"
      // delta="0.998" hyperscore="32.9"
      // nextscore="12.2" y_score="10.7"
      // y_ions="9" b_score="0.0" b_ions="0"
      // pre="VLGR" post="VEFM"
      // seq="TGSQGQCTQVR"
      // missed_cleavages="10">
      /*
       * id
      – the identifier for t
      his particular identified dom
      ain (s
      pectrum
      #).(i
      d
      #).(dom
      ain#)
      start
      – the first residue
      of t
      he dom
      ain
      end
      – the last residue
      of t
      he dom
      ain
      expect
      – the expe
      ctation va
      lue for t
      he peptide identification
      mh
      – the calculated pe
      ptide mass + a prot
      on
      delta
      – the spectrum
      mh m
      inus
      the calculated m
      h
      hyperscore
      – T
      ande
      m’s score for t
      he identification
      peak_count
      – the num
      ber of pe
      aks that matched be
      tween the theoretical
      and t
      he test mass spectrum
      pre
      – the four re
      sidue
      s pre
      ceding t
      he dom
      ain
      post
      – the four re
      sidue
      s fol
      lowing t
      he dom
      ain
      seq
      – the seque
      nce of t
      he dom
      ain
      missed_cleavages
      – the num
      ber of pot
      ential cleavage sites in this
      peptide seque
      nce*/

      // valeur généric du scan
      tandem_group.peptide_sp =
        PeptideXtp(
          m_qxmlStreamReader.attributes().value("seq").toString().simplified())
          .residueModifications(m_residueMassModificationMap)
          .makePeptideXtpSp();
      qDebug() << tandem_group.peptide_sp.get()->toString();
      PeptideEvidence *p_peptide_evidence =
        new PeptideEvidence(msp_msrun.get(),
                            m_qxmlStreamReader.attributes()
                              .value("id")
                              .toString()
                              .simplified()
                              .section(".", 0, 0)
                              .toUInt(),
                            false);

      p_peptide_evidence->setRetentionTime(tandem_group.retentionTime);
      p_peptide_evidence->setEvalue(m_qxmlStreamReader.attributes()
                                      .value("expect")
                                      .toString()
                                      .simplified()
                                      .toDouble());
      // qDebug() <<
      // "XtandemSaxHandler::startElement_domain
      // evalue "  <<
      // _p_peptide_match->getEvalue() << " scan
      // " << _p_peptide_match->get();
      /*
        pappso::pappso_double
        xtandem_mhtheoretical =
          attributes.value("mh").simplified().toDouble();
        pappso::pappso_double xtandem_delta =
          attributes.value("delta").simplified().toDouble();
      */
      // delta – the spectrum mh minus the
      // calculated mh

      // exp mass computed from X!Tandem mh :
      pappso::pappso_double exp_mass =
        tandem_group.mhplusObser - pappso::MHPLUS;


      p_peptide_evidence->setExperimentalMass(exp_mass);
      tandem_group.peptideMatch.setStart(m_qxmlStreamReader.attributes()
                                           .value("start")
                                           .toString()
                                           .simplified()
                                           .toUInt() -
                                         1);
      p_peptide_evidence->setCharge(tandem_group.charge);

      p_peptide_evidence->setParam(
        PeptideEvidenceParam::tandem_hyperscore,
        QVariant(
          m_qxmlStreamReader.attributes().value("hyperscore").toDouble()));

      p_peptide_evidence->setIdentificationDataSource(
        mp_identificationDataSource);
      p_peptide_evidence->setChecked(true);


      // missing information
      // peptide.set_hypercorr(Float.valueOf(attrs.getValue("hyperscore")));
      // peptide.set_pre(attrs.getValue("pre"));
      // peptide.set_post(attrs.getValue("post"));
      // qDebug() << "startElement_domain end" ;


      while(m_qxmlStreamReader.readNextStartElement())
        {
          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "aa")
            {
              //<aa type="M" at="624"
              // modified="15.99491" />
              // qDebug() << "startElement_aa ";
              pappso::AaModificationP modif = nullptr;
              if(m_qxmlStreamReader.attributes().value("pm").isEmpty())
                {

                  modif =
                    pappso::Utils::guessAaModificationPbyMonoisotopicMassDelta(
                      (pappso::Enums::AminoAcidChar)m_qxmlStreamReader.attributes()
                        .value("type")
                        .toLatin1()[0],
                      m_qxmlStreamReader.attributes()
                        .value("modified")
                        .toString()
                        .simplified()
                        .toDouble());
                }
              else
                {
                  //<aa type="P" at="59"
                  // modified="31.98983" pm="E" />
                  //<aa type="C" at="64"
                  // modified="-15.97716" pm="S" />
                  // point mutation
                  QChar mut_from(
                    m_qxmlStreamReader.attributes().value("type")[0]);
                  QChar mut_to(m_qxmlStreamReader.attributes().value("pm")[0]);
                  modif = pappso::AaModification::getInstanceMutation(mut_from,
                                                                      mut_to);
                }
              unsigned int position_in_prot = m_qxmlStreamReader.attributes()
                                                .value("at")
                                                .toString()
                                                .simplified()
                                                .toUInt() -
                                              1;
              tandem_group.peptide_sp.get()->addAaModification(
                modif, position_in_prot - tandem_group.peptideMatch.getStart());
              // qDebug() << "startElement_aa end" ;
              m_qxmlStreamReader.skipCurrentElement();
            }
          else
            {
              m_qxmlStreamReader.raiseError(
                QObject::tr("Not an X!Tandem input "
                            "file (no bioml)"));
              m_qxmlStreamReader.skipCurrentElement();
            }
        }

      /*********************
       * endElement_
       *******************/

      tandem_group.peptide_sp =
        mp_project->getPeptideStore().getInstance(tandem_group.peptide_sp);

      p_peptide_evidence->setPeptideXtpSp(tandem_group.peptide_sp);

      tandem_group.peptideMatch.setPeptideEvidenceSp(
        p_peptide_evidence->getIdentificationDataSource()
          ->getPeptideEvidenceStore()
          .getInstance(p_peptide_evidence));
      if(tandem_group.p_proteinMatch == nullptr)
        {
          throw pappso::PappsoException(QString("ERROR in %1, %2, %3 "
                                                "domain : "
                                                "_p_protein_match == nullptr")
                                          .arg(__FILE__)
                                          .arg(__FUNCTION__)
                                          .arg(__LINE__));
        }

      tandem_group.p_proteinMatch->addPeptideMatch(tandem_group.peptideMatch);

      delete p_peptide_evidence;
    }
}


void
TandemReader::readGroupTypeParameters(TandemGroup &tandem_group)

{

  qDebug() << tandem_group.label;
  while(m_qxmlStreamReader.readNextStartElement())
    {

      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "note")
        {
          QString type =
            m_qxmlStreamReader.attributes().value("type").toString();
          QString label =
            m_qxmlStreamReader.attributes().value("label").toString();
          QString text = m_qxmlStreamReader.readElementText();

          //<group label="input parameters" type="parameters">
          //<note type="input" label="list path, default
          // parameters">/gorgone/pappso/tmp/temp_condor_job8533994640337729751189420695540169/QExactive_analysis_FDR_nosemi.xml</note>
          if(label == "list path, default parameters")
            {
              mp_identificationDataSource->setIdentificationEngineParam(
                IdentificationEngineParam::tandem_param, text);
            }
          /*
          <note type="input" label="list path, taxonomy
          information">/gorgone/pappso/tmp/temp_condor_job8533994640337729751189420695540169/database.xml</note>
          <note type="input" label="output, histogram column width">30</note>
          <note type="input" label="output, histograms">yes</note>
          <note type="input" label="output, maximum valid expectation
          value">0.05</note> <note type="input" label="output, maximum valid
          protein expectation value">0.05</note> <note type="input"
          label="output, one sequence copy">yes</note> <note type="input"
          label="output, parameters">yes</note> <note type="input"
          label="output,
          path">/gorgone/pappso/formation/TD/xml_tandem/20120906_balliau_extract_1_A02_urzb-1.xml</note>
          <note type="input" label="output, path hashing">no</note>
          <note type="input" label="output, performance">yes</note>
          <note type="input" label="output, proteins">yes</note>
          <note type="input" label="output, results">valid</note>
          <note type="input" label="output, sequences">yes</note>
          <note type="input" label="output, sort results by">spectrum</note>
          <note type="input" label="output, spectra">yes</note>
          <note type="input" label="output, xsl path">tandem-style.xsl</note>
          <note type="input" label="protein, C-terminal residue modification
          mass">0.0</note> <note type="input" label="protein, N-terminal residue
          modification mass">0.0</note> <note type="input" label="protein,
          cleavage C-terminal mass change">+17.00305</note> <note type="input"
          label="protein, cleavage N-terminal mass change">+1.00794</note> <note
          type="input" label="protein, cleavage semi">no</note> <note
          type="input" label="protein, cleavage site">[RK]|{P}</note> <note
          type="input" label="protein, modified residue mass file"></note> <note
          type="input" label="protein, quick acetyl">yes</note> <note
          type="input" label="protein, quick pyrolidone">yes</note> <note
          type="input" label="protein, stP bias">yes</note> <note type="input"
          label="protein, taxon">usedefined</note> <note type="input"
          label="refine">yes</note> <note type="input" label="refine, cleavage
          semi">no</note> <note type="input" label="refine, maximum valid
          expectation value">0.01</note> <note type="input" label="refine,
          modification mass">57.02146@C</note> <note type="input" label="refine,
          modification mass 1"></note> <note type="input" label="refine, point
          mutations">no</note> <note type="input" label="refine, potential
          C-terminus modifications"></note> <note type="input" label="refine,
          potential N-terminus modifications">+42.01056@[</note> <note
          type="input" label="refine, potential modification
          mass">15.99491@M</note> <note type="input" label="refine, potential
          modification mass 1"></note> <note type="input" label="refine,
          potential modification motif"></note> <note type="input"
          label="refine, potential modification motif 1"></note> <note
          type="input" label="refine, spectrum synthesis">yes</note> <note
          type="input" label="refine, unanticipated cleavage">no</note> <note
          type="input" label="refine, use potential modifications for full
          refinement">yes</note> <note type="input" label="residue, modification
          mass">57.02146@C</note> <note type="input" label="residue,
          modification mass 1"></note> <note type="input" label="residue,
          potential modification mass">15.99491@M</note> <note type="input"
          label="residue, potential modification motif"></note> <note
          type="input" label="scoring, a ions">no</note> <note type="input"
          label="scoring, b ions">yes</note> <note type="input" label="scoring,
          c ions">no</note> <note type="input" label="scoring, cyclic
          permutation">yes</note> <note type="input" label="scoring, include
          reverse">yes</note> <note type="input" label="scoring, maximum missed
          cleavage sites">1</note> <note type="input" label="scoring, minimum
          ion count">4</note> <note type="input" label="scoring, x
          ions">no</note> <note type="input" label="scoring, y ions">yes</note>
          <note type="input" label="scoring, z ions">no</note>
          <note type="input" label="spectrum, dynamic range">100.0</note>
          <note type="input" label="spectrum, fragment mass
          type">monoisotopic</note> <note type="input" label="spectrum, fragment
          monoisotopic mass error">0.02</note> <note type="input"
          label="spectrum, fragment monoisotopic mass error
          units">Daltons</note> <note type="input" label="spectrum, maximum
          parent charge">4</note> <note type="input" label="spectrum, minimum
          fragment mz">150.0</note> <note type="input" label="spectrum, minimum
          parent m+h">500.0</note> <note type="input" label="spectrum, minimum
          peaks">15</note> <note type="input" label="spectrum, neutral loss
          mass">18.01057</note> <note type="input" label="spectrum, neutral loss
          window">0.02</note> <note type="input" label="spectrum, parent
          monoisotopic mass error minus">10</note> <note type="input"
          label="spectrum, parent monoisotopic mass error plus">10</note> <note
          type="input" label="spectrum, parent monoisotopic mass error
          units">ppm</note> <note type="input" label="spectrum, parent
          monoisotopic mass isotope error">yes</note>
          */
          //<note type="input" label="spectrum,
          // path">/gorgone/pappso/formation/TD/mzXML/20120906_balliau_extract_1_A02_urzb-1.mzXML</note>

          if(label == "spectrum, path")
            {
              //_sp_msrun.get()->setFileName(_current_text);
              // already set by tandem info parser
            }

          /*
          <note type="input" label="spectrum, sequence batch size">1000</note>
          <note type="input" label="spectrum, threads">1</note>
          <note type="input" label="spectrum, total peaks">100</note>
          <note type="input" label="spectrum, use contrast angle">no</note>
          <note type="input" label="spectrum, use neutral loss
          window">yes</note> <note type="input" label="spectrum, use noise
          suppression">yes</note>
          </group>

          */

          //<group label="unused input parameters"  type="parameters">

          /*
            <note type="input" label="protein, use minimal
          annotations">yes</note> <note type="input" label="refine, modification
          mass 2"></note> <note type="input" label="refine, potential
          modification mass 2"></note> <note type="input" label="refine,
          potential modification motif 2"></note> <note type="input"
          label="residue, modification mass 2"></note> <note type="input"
          label="residue, potential modification mass 1"></note> <note
          type="input" label="residue, potential modification mass 2"></note>
          <note type="input" label="residue, potential modification motif
          1"></note> <note type="input" label="residue, potential modification
          motif 2"></note> <note type="input" label="scoring, pluggable
          scoring">no</note>
          </group>
          */

          //<group label="performance parameters" type="parameters">

          //<note label="list path, sequence source
          //#1">/gorgone/pappso/formation/TD/Database/Genome_Z_mays_5a.fasta</note>
          //<note label="list path, sequence source
          //#2">/gorgone/pappso/formation/TD/Database/contaminants_standarts.fasta</note>
          if(label.startsWith("list path, sequence source #"))
            {
              mp_identificationDataSource->addFastaFile(
                mp_project->getFastaFileStore().getInstance(FastaFile(text)));
            }

          /*
          <note label="list path, sequence source description #1">no
          description</note> <note label="list path, sequence source description
          #2">no description</note> <note label="modelling, duplicate peptide
          ids">6019</note> <note label="modelling, duplicate
          proteins">19735</note> <note label="modelling, estimated false
          positives">18</note> <note label="modelling, reversed sequence false
          positives">20</note> <note label="modelling, spectrum noise
          suppression ratio">0.00</note>
          */
          //<note label="modelling, total peptides used">96618641</note>
          if(label == "modelling, total peptides used")
            {
              mp_identificationDataSource->setIdentificationEngineStatistics(
                IdentificationEngineStatistics::total_peptide_used,
                text.toUInt());
            }

          //<note label="modelling, total proteins used">273656</note>
          if(label == "modelling, total proteins used")
            {
              mp_identificationDataSource->setIdentificationEngineStatistics(
                IdentificationEngineStatistics::total_proteins_used,
                text.toUInt());
            }
          //<note label="modelling, total spectra assigned">7464</note>
          if(label == "modelling, total spectra assigned")
            {
              mp_identificationDataSource->setIdentificationEngineStatistics(
                IdentificationEngineStatistics::total_spectra_assigned,
                text.toUInt());
            }
          //<note label="modelling, total spectra used">12199</note>
          if(label == "modelling, total spectra used")
            {

              qDebug() << label;
              mp_identificationDataSource->setIdentificationEngineStatistics(
                IdentificationEngineStatistics::total_spectra_used,
                text.toUInt());
            }
          //<note label="modelling, total unique assigned">6260</note>
          if(label == "modelling, total unique assigned")
            {

              qDebug() << label;
              mp_identificationDataSource->setIdentificationEngineStatistics(
                IdentificationEngineStatistics::total_unique_assigned,
                text.toUInt());
            }
          qDebug() << label;
          if(label == "spectrum, timstof MS2 centroid parameters")
            {
              qDebug() << label;
              mp_identificationDataSource->setTimstofMs2CentroidParameters(
                text);

              if((msp_msrun.get()->getFileName().endsWith(".tdf")) ||
                 (msp_msrun.get()->getFileName().endsWith(".d")))
                {
                  // this is a TimsTOF tandem result file : scan numbers are in
                  // fact spectrum index: we have to notice this
                  mp_identificationDataSource->getPeptideEvidenceStore()
                    .ensureSpectrumIndexRef();
                }
            }
          if(label == "output, spectrum index")
            {
              // TODO in pappsomspp : change tandem output to explicitly tell if
              // we are dealing with spectrum index
              qDebug() << label;

              if(text == "true")
                { // this MUST be spectrum index instead of scan numbers
                  mp_identificationDataSource->getPeptideEvidenceStore()
                    .ensureSpectrumIndexRef();
                }
            }
          if(label == "spectrum, timstof MS2 filters")
            {
              qDebug() << label;
              // this is a TimsTOF tandem result file : scan numbers are in fact
              // spectrum index:
              // we have to notice this
              if((msp_msrun.get()->getFileName().endsWith(".tdf")) ||
                 (msp_msrun.get()->getFileName().endsWith(".d")))
                {
                  // this is a TimsTOF tandem result file : scan numbers are in
                  // fact spectrum index: we have to notice this
                  mp_identificationDataSource->getPeptideEvidenceStore()
                    .ensureSpectrumIndexRef();
                }
            }
          //<note label="process, start time">2013:12:20:16:47:19</note>

          //<note label="process, version">X! Tandem Sledgehammer
          //(2013.09.01.1)</note>
          if(label == "process, version")
            {
              QRegularExpressionMatch rx =
                QRegularExpression("\\((.*)\\)").match(text);
              if(rx.hasMatch())
                {
                  mp_identificationDataSource->setIdentificationEngineVersion(
                    rx.captured(1));
                }
              qDebug() << mp_identificationDataSource
                            ->getIdentificationEngineVersion();
            }
          /*
          <note label="quality values">243 476 437 382 384 417 399 416 346 387
          390 382 321 355 311 283 253 272 251 228</note> <note label="refining,
          # input models">4893</note> <note label="refining, # input
          spectra">5520</note> <note label="refining, # partial
          cleavage">326</note> <note label="refining, # point
          mutations">0</note> <note label="refining, # potential
          C-terminii">0</note> <note label="refining, # potential
          N-terminii">392</note> <note label="refining, # unanticipated
          cleavage">0</note> <note label="timing, initial modelling total
          (sec)">170.96</note> <note label="timing, initial modelling/spectrum
          (sec)">0.0140</note> <note label="timing, load sequence models
          (sec)">0.33</note> <note label="timing, refinement/spectrum
          (sec)">0.0141</note>
          </group>
          */
        }


      else
        {
          m_qxmlStreamReader.raiseError(
            QObject::tr("Not an X!Tandem input "
                        "file (no bioml)"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}
