/**
 * \file src/input/pepxml/pepxmlreader.cpp
 * \date 19/9/2022
 * \author Olivier Langella
 * \brief new method to read pep 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 "pepxmlreader.h"
#include "../../utils/utils.h"

PepXmlReader::PepXmlReader(
  pappso::UiMonitorInterface *p_monitor,
  Project *p_project,
  IdentificationGroup *p_identification_group,
  IdentificationPepXmlFile *p_identification_data_source)
{
  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();
}

PepXmlReader::~PepXmlReader()
{
}


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

          readMsms_pipeline_analysis();
          /*
        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 a pep xml input file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}


void
PepXmlReader::readMsms_pipeline_analysis()
{

  // <msms_pipeline_analysis date="2015-01-19T13:28:41"
  // xmlns="http://regis-web.systemsbiology.net/pepXML"
  // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  // xsi:schemaLocation="http://sashimi.sourceforge.net/schema_revision/pepXML/pepXML_v117.xsd"
  // summary_xml="/gorgone/pappso/abrf_2015/mzXML/JD_06232014_sample1-A.pep.xml">
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "msms_pipeline_analysis")
    {
      m_qxmlStreamReader.attributes().value("key");

      QString original_filename =
        m_qxmlStreamReader.attributes().value("summary_xml").toString();
      // m_qxmlStreamReader.skipCurrentElement();

      while(m_qxmlStreamReader.readNextStartElement())
        {

          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "msms_run_summary")
            {
              readMsms_run_summary();
            }
          else
            {
              m_qxmlStreamReader.skipCurrentElement();
            }
        }
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}


void
PepXmlReader::readMsms_run_summary()
{

  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "msms_run_summary")
    {

      // <msms_run_summary
      // base_name="/gorgone/pappso/abrf_2015/mzXML/JD_06232014_sample1-A"
      // msManufacturer="Thermo Scientific" msModel="Q Exactive"
      // raw_data_type="raw" raw_data=".mzXML">
      QString raw_data_type =
        m_qxmlStreamReader.attributes().value("raw_data_type").toString();

      if(raw_data_type == "d")
        {
          m_msDataFormat = pappso::Enums::MsDataFormat::brukerTims;

          msp_msrun.get()->setMsDataFormat(m_msDataFormat);
        }

      QString old_file;
      if(!m_currentCompleteMsrunFilePath.isEmpty())
        {
          old_file = m_currentCompleteMsrunFilePath;
        }
      m_currentCompleteMsrunFilePath =
        QString("%1.%2")
          .arg(m_qxmlStreamReader.attributes().value("base_name").toString())
          .arg(m_qxmlStreamReader.attributes().value("raw_data").toString());
      if((!old_file.isEmpty()) &&
         (QFileInfo(m_currentCompleteMsrunFilePath).baseName() !=
          QFileInfo(old_file).baseName()))
        {
          throw pappso::PappsoException(
            QObject::tr(
              "ERROR reading pepxml file :\ni2MassChroQ does not "
              "support identification source files containing results "
              "from multiple MS runs (%1 != %2)")
              .arg(old_file)
              .arg(m_currentCompleteMsrunFilePath));
        }
      msp_msrun.get()->setFileName(
        m_qxmlStreamReader.attributes().value("base_name").toString());
      msp_msrun.get()->setSampleName(
        QFileInfo(m_currentCompleteMsrunFilePath.replace("\\", "/"))
          .baseName());
      if(m_msDataFormat == pappso::Enums::MsDataFormat::brukerTims)
        {
          msp_msrun.get()->setFileName(m_currentCompleteMsrunFilePath);
          /*
                    msp_msrun.get()->setSampleName(QString("%1.d").arg(
                      QFileInfo(m_currentCompleteMsrunFilePath.replace("\\",
             "/")) .baseName()));*/
        }

      std::size_t count = 0;
      while(m_qxmlStreamReader.readNextStartElement())
        {

          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "search_summary")
            {
              readSearch_summary();
            }
          else if(m_qxmlStreamReader.name().toString() == "spectrum_query")
            {

              if((count % 1000) == 0)
                {
                  if(mp_monitor->shouldIstop())
                    {
                      throw pappso::ExceptionInterrupted(QObject::tr(
                        "pepxml file reading interrupted by the user"));
                    }
                }
              readSpectrum_query();
              count++;
            }
          else
            {
              m_qxmlStreamReader.skipCurrentElement();
            }
        }
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}

void
PepXmlReader::readSearch_summary()
{

  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "search_summary")
    {

      // <search_summary
      // base_name="/gorgone/pappso/moulon/users/Olivier/Delphine_Pecqueur/mzXML/330_01_01_C3G3_150122_01"
      // search_engine="X! Tandem (k-score)" precursor_mass_type="monoisotopic"
      // fragment_mass_type="monoisotopic" search_id="1">
      QString search_engine_str =
        m_qxmlStreamReader.attributes().value("search_engine").toString();

      m_searchEngine = IdentificationEngine::unknown;
      if(search_engine_str == "X! Tandem (k-score)")
        {
          // search_engine="X! Tandem (k-score)"
          m_searchEngine = IdentificationEngine::XTandem;
        }

      else if(search_engine_str == "X! Tandem")
        {
          // files coming from msfragger
          m_searchEngine = IdentificationEngine::XTandem;
        }

      else if(search_engine_str == "OMSSA")
        {
          m_searchEngine = IdentificationEngine::OMSSA;
        }
      else if(search_engine_str == "Comet")
        {
          m_searchEngine = IdentificationEngine::Comet;
        }
      else if(search_engine_str == "MS-GF+")
        {
          m_searchEngine = IdentificationEngine::MSGFplus;
        }

      if(m_searchEngine == IdentificationEngine::unknown)
        {
          throw pappso::PappsoException(
            QObject::tr(
              "ERROR reading pepxml file :\nsearch engine %1 is not known.")
              .arg(search_engine_str));
        }


      mp_identificationDataSource->setIdentificationEngine(m_searchEngine);

      while(m_qxmlStreamReader.readNextStartElement())
        {

          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "search_database")
            {

              // <search_database
              // local_path="/gorgone/pappso/abrf_2015/fasta/iPRG2015.fasta"
              // type="AA"/>
              //<search_database
              // local_path="/gorgone/pappso/abrf_2015/fasta/iPRG2015.TargDecoy.fasta"
              // database_name="SearchDB_1" size_in_db_entries="13256"
              // type="NA"/>

              FastaFile fasta_file(
                m_qxmlStreamReader.attributes().value("local_path").toString());
              if(!m_qxmlStreamReader.attributes()
                    .value("database_name")
                    .isEmpty())
                {
                  fasta_file.setXmlId(m_qxmlStreamReader.attributes()
                                        .value("database_name")
                                        .toString());
                }
              mp_identificationDataSource->addFastaFile(
                mp_project->getFastaFileStore().getInstance(fasta_file));
              m_qxmlStreamReader.skipCurrentElement();
            }

          else if(m_qxmlStreamReader.name().toString() ==
                  "aminoacid_modification")
            {
              //<aminoacid_modification aminoacid="C" massdiff="57.021465"
              // mass="160.03065" variable="N"/>
              //<aminoacid_modification aminoacid="C" massdiff="-17.0265"
              // mass="143.00415" variable="Y" peptide_terminus="n"/>
              QString variable =
                m_qxmlStreamReader.attributes().value("variable").toString();
              if(!m_qxmlStreamReader.attributes()
                    .value("massdiff")
                    .toString()
                    .isEmpty())
                {
                  double mass_diff = m_qxmlStreamReader.attributes()
                                       .value("massdiff")
                                       .toDouble();
                  pappso::AaModificationP modif =
                    pappso::Utils::guessAaModificationPbyMonoisotopicMassDelta(
                      (pappso::Enums::AminoAcidChar)m_qxmlStreamReader.attributes()
                        .value("aminoacid")
                        .toLatin1()[0],
                      mass_diff);
                  if(!m_qxmlStreamReader.attributes()
                        .value("mass")
                        .toString()
                        .isEmpty())
                    {
                      if(variable == "Y")
                        {
                          m_mapModifications[m_qxmlStreamReader.attributes()
                                               .value("mass")
                                               .toDouble()] = modif;
                        }
                      else
                        {
                          m_mapFixedModifications[(pappso::Enums::AminoAcidChar)
                                                    m_qxmlStreamReader
                                                      .attributes()
                                                      .value("aminoacid")
                                                      .toString()[0]
                                                      .toLatin1()] = modif;
                          m_fixedModificationsMassList.push_back(
                            m_qxmlStreamReader.attributes()
                              .value("mass")
                              .toDouble());
                        }
                    }
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
          else if(m_qxmlStreamReader.name().toString() ==
                  "terminal_modification")
            {
              //<aminoacid_modification aminoacid="C" massdiff="57.021465"
              // mass="160.03065" variable="N"/>
              //<aminoacid_modification aminoacid="M" massdiff="15.9949"
              // mass="147.0354" variable="Y"/> <terminal_modification
              // massdiff="42.0106" protein_terminus="Y" mass="43.018425"
              // terminus="N" variable="Y"/>

              if(!m_qxmlStreamReader.attributes()
                    .value("massdiff")
                    .toString()
                    .isEmpty())
                {
                  double mass_diff = m_qxmlStreamReader.attributes()
                                       .value("massdiff")
                                       .toDouble();
                  pappso::AaModificationP modif =
                    pappso::Utils::guessAaModificationPbyMonoisotopicMassDelta(
                      (pappso::Enums::AminoAcidChar)m_qxmlStreamReader.attributes()
                        .value("aminoacid")
                        .toLatin1()[0],
                      mass_diff);
                  if(!m_qxmlStreamReader.attributes()
                        .value("mass")
                        .toString()
                        .isEmpty())
                    {
                      if(m_qxmlStreamReader.attributes()
                           .value("terminus")
                           .toString() == "N")
                        {
                          m_mapNterModifications[m_qxmlStreamReader.attributes()
                                                   .value("mass")
                                                   .toDouble()] = modif;
                        }
                    }
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
          else
            {
              // m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input
              // file"));
              m_qxmlStreamReader.skipCurrentElement();
            }
          // m_qxmlStreamReader.skipCurrentElement();
        }
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}


void
PepXmlReader::readSpectrum_query()
{

  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "spectrum_query")
    {
      SpectrumQuery spectrum_query;
      // <spectrum_query spectrum="JD_06232014_sample1-A.00005.00005.2"
      // start_scan="5" end_scan="5" precursor_neutral_mass="819.347822"
      // assumed_charge="2" index="1" retention_time_sec="1.4">
      // <spectrum_query spectrum="JD_06232014_sample1-A.00006.00006.2"
      // start_scan="6" end_scan="6" precursor_neutral_mass="870.405029296875"
      // assumed_charge="2" index="1">
      //         ion_mobility="1.3798064"
      if(!m_qxmlStreamReader.attributes().value("ion_mobility").isEmpty())
        {
          spectrum_query.ion_mobility =
            m_qxmlStreamReader.attributes().value("ion_mobility").toDouble();
        }
      spectrum_query.spectrum_ref =
        m_qxmlStreamReader.attributes().value("spectrum").toString();
      if(m_currentCompleteMsrunFilePath.isEmpty())
        {
          msp_msrun.get()->setFileName(
            QFileInfo(spectrum_query.spectrum_ref).baseName());
        }
      spectrum_query.start_scan =
        m_qxmlStreamReader.attributes().value("start_scan").toUInt();
      spectrum_query.end_scan =
        m_qxmlStreamReader.attributes().value("end_scan").toUInt();
      if(spectrum_query.start_scan != spectrum_query.end_scan)
        {
          throw pappso::PappsoException(
            QObject::tr("ERROR reading pepxml file :\nunable to read search "
                        "results from '%1' as start %2 and end %3 scans are "
                        "different")
              .arg(Utils::getIdentificationEngineName(m_searchEngine))
              .arg(spectrum_query.start_scan)
              .arg(spectrum_query.end_scan));
        }
      spectrum_query.scan = spectrum_query.start_scan;
      spectrum_query.charge =
        m_qxmlStreamReader.attributes().value("assumed_charge").toUInt();
      if(m_qxmlStreamReader.attributes()
           .value("retention_time_sec")
           .toString()
           .isEmpty())
        {
          QString message =
            QObject::tr(
              "ERROR reading pepxml file :\n"
              "unable to read search results from '%1' as retention time "
              "is not given in spectrum_query elements")
              .arg(Utils::getIdentificationEngineName(m_searchEngine));
          qDebug() << message;
          // throw new MSMSException(message);

          spectrum_query.retention_time = 0;
        }
      else
        {
          spectrum_query.retention_time = m_qxmlStreamReader.attributes()
                                            .value("retention_time_sec")
                                            .toDouble();
        }
      spectrum_query.precursor_neutral_mass = m_qxmlStreamReader.attributes()
                                                .value("precursor_neutral_mass")
                                                .toDouble();


      while(m_qxmlStreamReader.readNextStartElement())
        {

          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "search_result")
            {
              while(m_qxmlStreamReader.readNextStartElement())
                {

                  qDebug() << m_qxmlStreamReader.name();
                  if(m_qxmlStreamReader.name().toString() == "search_hit")
                    {
                      readSearch_hit(spectrum_query);
                    }
                  else
                    {
                      m_qxmlStreamReader.raiseError(
                        QObject::tr("Not a pep xml input file"));
                      m_qxmlStreamReader.skipCurrentElement();
                    }
                }
            }
          else
            {
              m_qxmlStreamReader.raiseError(
                QObject::tr("Not a pep xml input file"));
              m_qxmlStreamReader.skipCurrentElement();
            }
        }
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}


void
PepXmlReader::readSearch_hit(const SpectrumQuery &spectrum_query)
{

  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "search_hit")
    {

      std::vector<ProteinMatch *> protein_match_list;
      PeptideEvidence *peptide_evidence;
      PeptideMatch peptide_match;
      PeptideXtpSp peptide_sp;

      //_current_protein.setAccession(attributes.value("protein"));
      ProteinXtpSp sp_xtp_protein = ProteinXtp().makeProteinXtpSp();
      sp_xtp_protein.get()->setAccession(
        m_qxmlStreamReader.attributes().value("protein").toString());
      if(m_qxmlStreamReader.attributes().value("protein_descr").isEmpty())
        {
          sp_xtp_protein.get()->setCompleteDescription(
            m_qxmlStreamReader.attributes().value("protein").toString());
        }
      else
        {
          sp_xtp_protein.get()->setDescription(
            m_qxmlStreamReader.attributes().value("protein_descr").toString());
        }
      sp_xtp_protein.get()->setFastaFileP(
        mp_identificationDataSource->getFastaFileList()[0].get());

      sp_xtp_protein =
        mp_project->getProteinStore().getInstance(sp_xtp_protein);

      protein_match_list.push_back(
        mp_identificationGroup->getProteinMatchInstance(
          sp_xtp_protein.get()->getAccession()));

      protein_match_list[0]->setProteinXtpSp(sp_xtp_protein);

      protein_match_list[0]->setChecked(true);

      peptide_sp = PeptideXtp(m_qxmlStreamReader.attributes()
                                .value("peptide")
                                .toString()
                                .simplified())
                     .makePeptideXtpSp();


      for(std::pair<pappso::Enums::AminoAcidChar, pappso::AaModificationP>
            pair_aa_mod : m_mapFixedModifications)
        {
          peptide_sp.get()->addAaModificationOnAllAminoAcid(pair_aa_mod.second,
                                                            pair_aa_mod.first);
        }

      // if(m_mzFormat == pappso::MzFormat::brukerTims)
      //  {

      //     peptide_evidence = new PeptideEvidence(
      //       msp_msrun.get(), (2 * (spectrum_query.scan + 1)) + 1, true);
      //   }
      // else
      //   {
      if(m_searchEngine == IdentificationEngine::XTandem)
        {
          // targeted to MSFragger pepxml
          peptide_evidence =
            new PeptideEvidence(msp_msrun.get(), spectrum_query.scan - 1, true);
        }
      else
        {
          // old behaviour
          peptide_evidence =
            new PeptideEvidence(msp_msrun.get(), spectrum_query.scan, false);
        }
      //   }

      peptide_evidence->setRetentionTime(spectrum_query.retention_time);
      peptide_evidence->setCharge(spectrum_query.charge);

      /* 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 _mass_obser =
        attributes.value("calc_neutral_pep_mass").toDouble() +
        attributes.value("massdiff").toDouble();
    */

      //_p_peptide_evidence->setExperimentalMass(_mass_obser);
      peptide_evidence->setExperimentalMass(
        spectrum_query.precursor_neutral_mass);

      peptide_evidence->setIdentificationDataSource(
        mp_identificationDataSource);

      peptide_evidence->setIdentificationEngine(m_searchEngine);
      peptide_evidence->setChecked(true);


      while(m_qxmlStreamReader.readNextStartElement())
        {

          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "alternative_protein")
            {
              ProteinXtpSp sp_xtp_protein = ProteinXtp().makeProteinXtpSp();
              sp_xtp_protein.get()->setAccession(
                m_qxmlStreamReader.attributes().value("protein").toString());
              if(m_qxmlStreamReader.attributes()
                   .value("protein_descr")
                   .toString()
                   .isEmpty())
                {
                  sp_xtp_protein.get()->setCompleteDescription(
                    m_qxmlStreamReader.attributes()
                      .value("protein")
                      .toString());
                }
              else
                {
                  sp_xtp_protein.get()->setDescription(
                    m_qxmlStreamReader.attributes()
                      .value("protein_descr")
                      .toString());
                }
              sp_xtp_protein.get()->setFastaFileP(
                mp_identificationDataSource->getFastaFileList()[0].get());

              sp_xtp_protein =
                mp_project->getProteinStore().getInstance(sp_xtp_protein);

              protein_match_list.push_back(
                mp_identificationGroup->getProteinMatchInstance(
                  sp_xtp_protein.get()->getAccession()));

              protein_match_list.back()->setProteinXtpSp(sp_xtp_protein);

              protein_match_list.back()->setChecked(true);
              m_qxmlStreamReader.skipCurrentElement();
              qDebug() << m_qxmlStreamReader.name();
            }
          else if(m_qxmlStreamReader.name().toString() == "modification_info")
            {

              // <modification_info mod_nterm_mass="43.018389"
              // modified_peptide="SQRDCR">

              if(!m_qxmlStreamReader.attributes()
                    .value("mod_nterm_mass")
                    .isEmpty())
                {
                  pappso::AaModificationP modif = nullptr;
                  auto it =
                    m_mapNterModifications.find(m_qxmlStreamReader.attributes()
                                                  .value("mod_nterm_mass")
                                                  .toDouble());
                  if(it != m_mapNterModifications.end())
                    {
                      modif = it->second;
                    }
                  else
                    {
                      modif = pappso::Utils::
                        guessAaModificationPbyMonoisotopicMassDelta(
                          peptide_sp.get()->getAa(0).getAminoAcidChar(),
                          m_qxmlStreamReader.attributes()
                            .value("mod_nterm_mass")
                            .toDouble());
                    }

                  if(modif != nullptr)
                    {
                      peptide_sp.get()->addAaModification(modif, 0);
                    }
                }


              while(m_qxmlStreamReader.readNextStartElement())
                {

                  qDebug() << m_qxmlStreamReader.name();
                  if(m_qxmlStreamReader.name().toString() ==
                     "mod_aminoacid_mass")
                    {
                      //<modification_info
                      // modified_peptide="C[143]GNQAAIM[147]ELDDTLK">
                      //<mod_aminoacid_mass mass="143.00415" position="1"/>

                      double mass = m_qxmlStreamReader.attributes()
                                      .value("mass")
                                      .toDouble();

                      auto itfix_find =
                        std::find(m_fixedModificationsMassList.begin(),
                                  m_fixedModificationsMassList.end(),
                                  mass);
                      if(itfix_find != m_fixedModificationsMassList.end())
                        {
                          // already done
                        }
                      else
                        {

                          unsigned int position =
                            m_qxmlStreamReader.attributes()
                              .value("position")
                              .toUInt() -
                            1;
                          const pappso::Aa aa(peptide_sp.get()
                                                ->getSequence()[position]
                                                .toLatin1());
                          double mass_modif = mass - aa.getMass();


                          pappso::AaModificationP modif = nullptr;
                          auto it = m_mapModifications.find(mass);
                          if(it != m_mapModifications.end())
                            {
                              modif = it->second;
                            }
                          else
                            {

                              modif = pappso::Utils::
                                guessAaModificationPbyMonoisotopicMassDelta(
                                  aa.getAminoAcidChar(), mass_modif);
                            }

                          if(modif != nullptr)
                            {
                              peptide_sp.get()->addAaModification(modif,
                                                                  position);
                            }
                        }
                    }
                  m_qxmlStreamReader.skipCurrentElement();
                }
              qDebug() << m_qxmlStreamReader.name();
            }
          else if(m_qxmlStreamReader.name().toString() == "search_score")
            {
              readSearch_score(peptide_evidence);
              qDebug() << m_qxmlStreamReader.name();
            }
          else if(m_qxmlStreamReader.name().toString() == "analysis_result")
            {
              // readSearch_score(peptide_evidence);


              while(m_qxmlStreamReader.readNextStartElement())
                {

                  qDebug() << m_qxmlStreamReader.name();
                  if(m_qxmlStreamReader.name().toString() ==
                     "peptideprophet_result")
                    {
                      peptide_evidence->setParam(
                        PeptideEvidenceParam::peptide_prophet_probability,
                        m_qxmlStreamReader.attributes()
                          .value("probability")
                          .toDouble());
                    }
                  else if(m_qxmlStreamReader.name().toString() ==
                          "interprophet_result")
                    {
                      peptide_evidence->setParam(
                        PeptideEvidenceParam::peptide_inter_prophet_probability,
                        m_qxmlStreamReader.attributes()
                          .value("probability")
                          .toDouble());
                    }

                  m_qxmlStreamReader.skipCurrentElement();
                }
              qDebug() << m_qxmlStreamReader.name();
            }
        }


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

      peptide_evidence->setPeptideXtpSp(peptide_sp);

      peptide_match.setPeptideEvidenceSp(
        peptide_evidence->getIdentificationDataSource()
          ->getPeptideEvidenceStore()
          .getInstance(peptide_evidence));
      if(protein_match_list.size() == 0)
        {
          throw pappso::PappsoException(
            QObject::tr("ERROR "
                        "PepXmlSaxHandler::endElement_search_hit:\n_p_protein_"
                        "match_list.size() == 0"));
        }

      for(auto &protein_match : protein_match_list)
        {
          protein_match->addPeptideMatch(peptide_match);
        }

      delete peptide_evidence;
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}


/*
 * <search_score name="xcorr" value="0.528"/> <search_score name="deltacn"
 * value="0.059"/> <search_score name="deltacnstar" value="0.000"/>
 * <search_score name="spscore" value="29.4"/> <search_score name="sprank"
 * value="2"/> <search_score name="expect" value="1.00E+00"/>
 */
void
PepXmlReader::readSearch_score(PeptideEvidence *peptide_evidence)
{
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "search_score")
    {

      QString name = m_qxmlStreamReader.attributes().value("name").toString();
      QString valueStr =
        m_qxmlStreamReader.attributes().value("value").toString();
      if(!valueStr.isEmpty())
        {
          if(name == "expect")
            {
              peptide_evidence->setEvalue(valueStr.simplified().toDouble());
            }
          else if(name == "EValue")
            {
              peptide_evidence->setEvalue(valueStr.simplified().toDouble());
            }

          IdentificationEngine identification_engine =
            peptide_evidence->getIdentificationEngine();
          if(identification_engine == IdentificationEngine::OMSSA)
            {
              if(name == "pvalue")
                {
                  peptide_evidence->setParam(PeptideEvidenceParam::omssa_pvalue,
                                             valueStr.simplified().toDouble());
                }
              else if(name == "expect")
                {
                  peptide_evidence->setParam(PeptideEvidenceParam::omssa_evalue,
                                             valueStr.simplified().toDouble());
                }
            }
          else if(identification_engine == IdentificationEngine::XTandem)
            {
              if(name == "hyperscore")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::tandem_hyperscore,
                    QVariant(valueStr.simplified().toDouble()));
                }
            }
          else if(identification_engine == IdentificationEngine::Comet)
            {
              if(name == "xcorr")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_xcorr,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "deltacn")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_deltacn,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "deltacnstar")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_deltacnstar,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "spscore")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_spscore,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "sprank")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_sprank,
                    QVariant(valueStr.simplified().toInt()));
                }
              else if(name == "expect")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::comet_expectation_value,
                    QVariant(valueStr.simplified().toDouble()));
                  peptide_evidence->setEvalue(valueStr.simplified().toDouble());
                }
            }
          else if(identification_engine == IdentificationEngine::MSGFplus)
            {
              if(name == "raw")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::msgfplus_raw,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "SpecEValue")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::msgfplus_SpecEValue,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "EValue")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::msgfplus_EValue,
                    QVariant(valueStr.simplified().toDouble()));
                  peptide_evidence->setEvalue(valueStr.simplified().toDouble());
                }

              else if(name == "denovo")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::msgfplus_denovo,
                    QVariant(valueStr.simplified().toDouble()));
                }
              else if(name == "IsotopeError")
                {
                  peptide_evidence->setParam(
                    PeptideEvidenceParam::msgfplus_isotope_error,
                    QVariant(valueStr.simplified().toInt()));
                }
            }
        }
      m_qxmlStreamReader.skipCurrentElement();
    }
  else
    {
      m_qxmlStreamReader.raiseError(QObject::tr("Not a pep xml input file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}
