/**
 * \file src/input/xpipreader.cpp
 * \date 23/8/2022
 * \author Olivier Langella
 * \brief new method to read XPIP i2MassChroQ 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 "xpipreader.h"
#include <pappsomspp/core/exception/exceptionnotfound.h>
#include <pappsomspp/core/exception/exceptioninterrupted.h>
#include <pappsomspp/core/peptide/peptideproformaparser.h>

XpipReader::XpipReader(pappso::UiMonitorInterface *p_monitor,
                       Project *p_project)
{
  mp_monitor = p_monitor;
  mp_project = p_project;
}

XpipReader::~XpipReader()
{
}

bool
XpipReader::isI2masschroqXpip() const
{
  return m_isI2masschroqXpip;
}


void
XpipReader::readStream()
{

  qDebug();
  m_isI2masschroqXpip = true;
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "xpip")
        {
          QString xpip_version =
            m_qxmlStreamReader.attributes().value("version").toString();
          m_isI2masschroqXpip = true;

          readDescription();
          readCounts();
          readFilterParams();
          readFastaFileList();
          readContaminants();
          readDecoys();
          readMsrunList();
          if(readMsrunAlignmentGroupList())
            {
              m_qxmlStreamReader.readNextStartElement();
              qDebug() << m_qxmlStreamReader.name();
            }
          readIdentificationSourceList();
          readProteinList();
          readPeptideList();

          if(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() ==
                 "identification_group_list")
                { /*

     <identification_group_list>
         <identification_group>
         */
                  while(readIdentificationGroup())
                    {
                    }
                }
            }
          mp_project->updateAutomaticFilters(m_automaticFilterParameters);
        }
      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }

  else
    {
      m_isI2masschroqXpip = false;
      m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}

void
XpipReader::readDescription()
{
  //<description version="0.4.18" grouping="peptidemass" combine="true" mode="2"
  // ptm="0" date="2021-01-04T14:25:17"/>

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

          QString i2m_version =
            m_qxmlStreamReader.attributes().value("version").toString();
          mp_project->setProjectMode(ProjectMode::individual);
          if(m_qxmlStreamReader.attributes().value("combine").toString() ==
             "true")
            {
              mp_project->setProjectMode(ProjectMode::combined);
            }

          if(m_qxmlStreamReader.attributes().value("ptm").toString().isEmpty())
            {
              mp_project->setPtmMode(PtmMode::none);
            }
          else
            {
              mp_project->setPtmMode(static_cast<PtmMode>(
                (m_qxmlStreamReader.attributes().value("ptm").toInt())));
            }

          if(m_qxmlStreamReader.attributes().value("mode").toString().isEmpty())
            {
            }
          else
            {
              mp_project->setProjectMode(static_cast<ProjectMode>(
                m_qxmlStreamReader.attributes().value("mode").toInt()));
            }
        }

      m_qxmlStreamReader.skipCurrentElement();
    }

  else
    {
      m_isI2masschroqXpip = false;
      m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}

void
XpipReader::readCounts()
{

  //<counts proteins="6804" peptides="7716" peptide_evidences="14744"
  // protein_matches="6804"/>
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "counts")
        {

          m_totalProteins = (std::size_t)m_qxmlStreamReader.attributes()
                              .value("proteins")
                              .toLong();
          m_totalPeptides = (std::size_t)m_qxmlStreamReader.attributes()
                              .value("peptides")
                              .toLong();
          m_totalPeptideEvidences = (std::size_t)m_qxmlStreamReader.attributes()
                                      .value("peptide_evidences")
                                      .toLong();
          m_totalProteinMatches = (std::size_t)m_qxmlStreamReader.attributes()
                                    .value("protein_matches")
                                    .toLong();
          m_countProteins         = 0;
          m_countPeptides         = 0;
          m_countPeptideEvidences = 0;
          m_countProteinMatches   = 0;
          m_countTotal            = 0;

          m_total = m_totalProteins + m_totalPeptides +
                    m_totalPeptideEvidences + m_totalProteinMatches;

          mp_monitor->setTotalSteps(m_total);
          m_qxmlStreamReader.skipCurrentElement();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readFilterParams()
{
  //<filter_params pep_evalue="0.01" prot_evalue="0.01" pep_number="2"
  // cross_sample="false" peprepro="0"/>

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

          m_totalProteins = (std::size_t)m_qxmlStreamReader.attributes()
                              .value("proteins")
                              .toLong();

          if(!m_qxmlStreamReader.attributes().value("type").isEmpty())
            {
              m_automaticFilterParameters.setAutomaticFilterType(
                static_cast<AutomaticFilterType>(
                  m_qxmlStreamReader.attributes().value("type").toInt()));
              m_automaticFilterParameters.setFilterPeptideFDR(
                m_qxmlStreamReader.attributes().value("fdr").toDouble());
              m_automaticFilterParameters.setSvmprobThreshold(
                m_qxmlStreamReader.attributes().value("svm_prob").toDouble());
              m_automaticFilterParameters.setProteinSvmprobThreshold(
                m_qxmlStreamReader.attributes().value("prot_prob").toDouble());
            }

          m_automaticFilterParameters.setFilterPeptideEvalue(
            m_qxmlStreamReader.attributes().value("pep_evalue").toDouble());
          m_automaticFilterParameters.setFilterProteinEvalue(
            m_qxmlStreamReader.attributes().value("prot_evalue").toDouble());
          if(!m_qxmlStreamReader.attributes().value("prot_qvalue").isNull())
            {
              m_automaticFilterParameters.setFilterProteinQvalue(
                m_qxmlStreamReader.attributes()
                  .value("prot_qvalue")
                  .toDouble());
            }
          m_automaticFilterParameters.setFilterMinimumPeptidePerMatch(
            m_qxmlStreamReader.attributes().value("pep_number").toUInt());
          m_automaticFilterParameters.setFilterCrossSamplePeptideNumber(false);
          if(m_qxmlStreamReader.attributes()
               .value("cross_sample")
               .toString()
               .simplified() == "true")
            {
              m_automaticFilterParameters.setFilterCrossSamplePeptideNumber(
                true);
            }

          m_automaticFilterParameters.setFilterPeptideObservedInLessSamplesThan(
            m_qxmlStreamReader.attributes().value("peprepro").toUInt());

          m_qxmlStreamReader.skipCurrentElement();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readFastaFileList()
{
  /*
  <fasta_file_list> <fasta_file id="fastaa0"
path="/gorgone/pappso/formation/TD/Database/Genome_Z_mays_5a.fasta"/>
    <fasta_file id="fastaa1"
path="/gorgone/pappso/formation/TD/Database/contaminants_standarts.fasta"/>
</fasta_file_list>
*/

  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "fasta_file_list")
        {
          while(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "fasta_file")
                {
                  FastaFileSp fasta_file_sp =
                    mp_project->getFastaFileStore().getInstance(
                      FastaFile(m_qxmlStreamReader.attributes()
                                  .value("path")
                                  .toString()));
                  fasta_file_sp.get()->setXmlId(
                    m_qxmlStreamReader.attributes().value("id").toString());

                  m_mapFastaFiles.insert(std::pair<QString, FastaFileSp>(
                    m_qxmlStreamReader.attributes().value("id").toString(),
                    fasta_file_sp));
                  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
                  // __LINE__;
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}


void
XpipReader::readContaminants()
{

  //  <contaminants mode="3" regexp="^contaminant.*" fasta_id=""/>
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "contaminants")
        {

          qDebug();
          if(!m_qxmlStreamReader.attributes().value("mode").isEmpty())
            {
              mp_project->setContaminantRemovalMode(
                (ContaminantRemovalMode)m_qxmlStreamReader.attributes()
                  .value("mode")
                  .toUInt());
              qDebug() << (std::uint8_t)mp_project->getContaminantRemovalMode();
            }

          QString regexp(
            m_qxmlStreamReader.attributes().value("regexp").toString());
          QString fasta_id_list(
            m_qxmlStreamReader.attributes().value("fasta_id").toString());
          if(regexp.isEmpty() || regexp.isNull())
            {
              mp_project->getProteinStore().setContaminantSelectionType(
                ContaminantSelectionType::fastaFiles);
              if(!fasta_id_list.isEmpty())
                {
                  for(QString fasta_id : fasta_id_list.split(" "))
                    {
                      qDebug() << fasta_id;
                      mp_project->getProteinStore().addContaminantFastaFile(
                        m_mapFastaFiles.at(fasta_id).get());
                    }
                }
            }
          else
            {
              mp_project->getProteinStore().setRegexpContaminantPattern(regexp);
              mp_project->getProteinStore().setContaminantSelectionType(
                ContaminantSelectionType::regexp);
            }
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readDecoys()
{

  //<decoys regexp=".*reversed$" fasta_id=""/>
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "decoys")
        {
          QString regexp(
            m_qxmlStreamReader.attributes().value("regexp").toString());
          QString fasta_id_list(
            m_qxmlStreamReader.attributes().value("fasta_id").toString());
          if(regexp.isEmpty())
            {
              mp_project->getProteinStore().setDecoySelectionType(
                DecoySelectionType::fastaFiles);
              if(!fasta_id_list.isEmpty())
                {
                  for(QString fasta_id : fasta_id_list.split(" "))
                    {
                      mp_project->getProteinStore().addDecoyFastaFile(
                        m_mapFastaFiles.at(fasta_id).get());
                    }
                }
            }
          else
            {
              mp_project->getProteinStore().setDecoySelectionType(
                DecoySelectionType::regexp);
              mp_project->getProteinStore().setRegexpDecoyPattern(regexp);
            }

          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}


void
XpipReader::readMsrunList()
{
  /*
<msrun_list>
<msrun id="sampa0" name="20120906_balliau_extract_1_A01_urnb-1" format="0"
path="20120906_balliau_extract_1_A01_urnb-1"/> <msrun id="sampa1"
name="20120906_balliau_extract_1_A02_urzb-1" format="0"
path="20120906_balliau_extract_1_A02_urzb-1"/>
</msrun_list>
*/

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

                  MsRunSp sp_msrun = mp_project->getMsRunStore().getInstance(
                    m_qxmlStreamReader.attributes()
                      .value("path")
                      .toString()
                      .simplified());
                  sp_msrun.get()->setFileName(m_qxmlStreamReader.attributes()
                                                .value("path")
                                                .toString()
                                                .simplified());
                  sp_msrun.get()->setSampleName(m_qxmlStreamReader.attributes()
                                                  .value("name")
                                                  .toString()
                                                  .simplified());
                  sp_msrun.get()->setXmlId(m_qxmlStreamReader.attributes()
                                             .value("id")
                                             .toString()
                                             .simplified());
                  m_mapMsruns.insert(std::pair<QString, MsRunSp>(
                    sp_msrun.get()->getXmlId(), sp_msrun));
                  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
                  // __LINE__;
                  readStats(sp_msrun);
                }
            }
        }
      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

bool
XpipReader::readMsrunAlignmentGroupList()
{

  /*
    <msrun_alignment_group_list>
        <msrun_group name="All" reference="">
            <grouped_msrun id="sampa0"/>
            <grouped_msrun id="sampa1"/>
        </msrun_group>
    </msrun_alignment_group_list>
    */

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

                  MsRunAlignmentGroupSp sp_alignment_group =
                    std::make_shared<MsRunAlignmentGroup>(
                      mp_project,
                      m_qxmlStreamReader.attributes()
                        .value("name")
                        .toString()
                        .simplified());
                  if(m_qxmlStreamReader.attributes()
                       .value("name")
                       .toString()
                       .simplified() == "all_msrun")
                    {
                      mp_project->setAllMsRunAlignmentGroup(sp_alignment_group);
                    }
                  else
                    {
                      mp_project->addMsRunAlignmentGroupToList(
                        sp_alignment_group);
                    }
                  QString reference_id = m_qxmlStreamReader.attributes()
                                           .value("reference")
                                           .toString()
                                           .simplified();
                  if(reference_id != "")
                    {
                      sp_alignment_group->setMsRunReference(
                        m_mapMsruns.at(reference_id));
                    }

                  sp_alignment_group->setMassChroQRunStatusFromInt(
                    m_qxmlStreamReader.attributes().value("status").toUInt());

                  //

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

                              qDebug() << m_qxmlStreamReader.name();
                              if(m_qxmlStreamReader.name().toString() ==
                                 "grouped_msrun")
                                {
                                  MsRunSp ms_run = m_mapMsruns.at(
                                    m_qxmlStreamReader.attributes()
                                      .value("id")
                                      .toString()
                                      .simplified());
                                  sp_alignment_group
                                    ->addMsRunToMsRunAlignmentGroupList(ms_run);
                                  ms_run->setAlignmentGroup(sp_alignment_group);
                                  m_qxmlStreamReader.skipCurrentElement();
                                }
                              else
                                {
                                  m_isI2masschroqXpip = false;
                                  m_qxmlStreamReader.raiseError(QObject::tr(
                                    "Not an XPIP file: grouped_msrun "
                                    "element expected"));
                                  m_qxmlStreamReader.skipCurrentElement();
                                }
                            }

                          // m_qxmlStreamReader.skipCurrentElement();
                        }

                      else if(m_qxmlStreamReader.name().toString() ==
                              "group_params")
                        {
                          // alignment_params
                          readAlignmentParams();
                          // quanti_params
                          readQuantiParams();
                          // masschroq_params
                          readMasschroqParams(sp_alignment_group);
                          m_qxmlStreamReader.skipCurrentElement();
                        }
                    }
                }
            }

          return true;
        }
    }
  return false;
}

void
XpipReader::readStats(MsRunSp sp_msrun)
{

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

              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "stat")
                {
                  /*
                  <stat key="0" value="48.5"/>
                  */
                  // qDebug() << __FILE__ << " " << __FUNCTION__ << " "
                  // << __LINE__;

                  MsRunStatistics type = static_cast<MsRunStatistics>(
                    m_qxmlStreamReader.attributes().value("key").toUInt());
                  sp_msrun.get()->setMsRunStatistics(
                    type,
                    m_qxmlStreamReader.attributes().value("value").toString());
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }

          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

QVariant
XpipReader::string2QVariant(const QString &value)
{

  bool ok;
  QVariant var;
  long numberi = value.toLong(&ok);
  if(ok)
    {
      var.setValue(numberi);
    }
  else
    {
      double numberd = value.toDouble(&ok);
      if(ok)
        {
          var.setValue(numberd);
        }
      else
        {
          var.setValue(value);
        }
    }
  return var;
}
void
XpipReader::readParams(ProteinMatch *p_protein_match)
{
  while(m_qxmlStreamReader.readNextStartElement())
    {
      // qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "param")
        {

          ProteinParam type = static_cast<ProteinParam>(
            m_qxmlStreamReader.attributes().value("key").toUInt());
          p_protein_match->setParam(
            type,
            string2QVariant(
              m_qxmlStreamReader.attributes().value("value").toString()));
          m_qxmlStreamReader.skipCurrentElement();
        }
      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readParams(PeptideEvidenceSp peptide_evidence_sp)
{

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

          PeptideEvidenceParam type = static_cast<PeptideEvidenceParam>(
            m_qxmlStreamReader.attributes().value("key").toUInt());
          peptide_evidence_sp.get()->setParam(
            type,
            string2QVariant(
              m_qxmlStreamReader.attributes().value("value").toString()));
          m_qxmlStreamReader.skipCurrentElement();
        }
      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}


void
XpipReader::readIdentificationSourceList()
{
  /*
   *
  <identification_source_list>
      <identification_source id="identa0" msrun_id="msruna1"
  path="/gorgone/pappso/data_extraction_pappso/tandem_output/20120906_balliau_extract_1_A01_urnb-1.xml"
  engine="1" version="2017.2.1.4" fasta_ids="fastaa1 fastaa0"> <params> <param
  key="0" value="/tmp/xtpcpp-HDpOXY/QExactive_analysis_FDR.xml"/>
          </params>
          <stats>
              <stat key="1" value="7552"/>
              <stat key="2" value="11892"/>
              <stat key="3" value="138264921"/>
              <stat key="4" value="273656"/>
              <stat key="5" value="6478"/>
          </stats>
      </identification_source>
      */

  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "identification_source_list")
    {
      while(m_qxmlStreamReader.readNextStartElement())
        {
          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name().toString() == "identification_source")
            {
              //<identification_source id="identa0" msrun_id="msruna1"
              // path="/gorgone/pappso/data_extraction_pappso/tandem_output/20120906_balliau_extract_1_A01_urnb-1.xml"
              // engine="1" version="2017.2.1.4" fasta_ids="fastaa1
              // fastaa0">
              IdentificationEngine engine = static_cast<IdentificationEngine>(
                m_qxmlStreamReader.attributes().value("engine").toUInt());
              IdentificationDataSourceSp sp_current_identification_source;
              if(engine == IdentificationEngine::sage)
                {
                  sp_current_identification_source =
                    mp_project->getIdentificationDataSourceStore()
                      .buildIdentificationSageJsonFileSp(
                        QFileInfo(m_qxmlStreamReader.attributes()
                                    .value("path")
                                    .toString()
                                    .simplified()),
                        mp_project->getIdentificationDataSourceStore()
                          .getIdentificationDataSourceList()
                          .size(),
                        m_mapMsruns.at(m_qxmlStreamReader.attributes()
                                         .value("msrun_id")
                                         .toString()
                                         .simplified()));
                }
              else
                {
                  sp_current_identification_source =
                    mp_project->getIdentificationDataSourceStore().getInstance(
                      m_qxmlStreamReader.attributes()
                        .value("path")
                        .toString()
                        .simplified(),
                      engine,
                      m_mapMsruns.at(m_qxmlStreamReader.attributes()
                                       .value("msrun_id")
                                       .toString()
                                       .simplified()));
                  sp_current_identification_source->setMsRunSp(
                    m_mapMsruns.at(m_qxmlStreamReader.attributes()
                                     .value("msrun_id")
                                     .toString()
                                     .simplified()));
                  sp_current_identification_source->setIdentificationEngine(
                    engine);
                }
              sp_current_identification_source.get()->setXmlId(
                m_qxmlStreamReader.attributes()
                  .value("id")
                  .toString()
                  .simplified());
              m_mapIdentSources.insert(
                std::pair<QString, IdentificationDataSourceSp>(
                  sp_current_identification_source.get()->getXmlId(),
                  sp_current_identification_source));

              // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
              // __LINE__;
              // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
              // __LINE__;
              sp_current_identification_source->setIdentificationEngineVersion(
                m_qxmlStreamReader.attributes().value("version").toString());

              for(const QString &fasta_id : m_qxmlStreamReader.attributes()
                                              .value("fasta_ids")
                                              .toString()
                                              .split(" "))
                {
                  sp_current_identification_source.get()->addFastaFile(
                    m_mapFastaFiles.at(fasta_id));
                }
              qDebug();
              qDebug() << m_qxmlStreamReader.name();
              readParamsStats(sp_current_identification_source);

              qDebug() << m_qxmlStreamReader.name();
              // m_qxmlStreamReader.skipCurrentElement();
            }
          else
            {
              m_isI2masschroqXpip = false;
              m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
              m_qxmlStreamReader.skipCurrentElement();
            }
        }
    }
  else
    {
      m_isI2masschroqXpip = false;
      m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
}

void
XpipReader::readParamsStats(
  IdentificationDataSourceSp sp_current_identification_source)
{
  /*
   * <params>
              <param key="0"
   value="/tmp/xtpcpp-HDpOXY/QExactive_analysis_FDR.xml"/>
          </params>
          */
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "params")
        {
          while(m_qxmlStreamReader.readNextStartElement())
            {

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

                  IdentificationEngineParam type =
                    static_cast<IdentificationEngineParam>(
                      m_qxmlStreamReader.attributes().value("key").toUInt());
                  sp_current_identification_source.get()
                    ->setIdentificationEngineParam(
                      type,
                      string2QVariant(m_qxmlStreamReader.attributes()
                                        .value("value")
                                        .toString()));
                  m_qxmlStreamReader.skipCurrentElement();
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }

          m_qxmlStreamReader.skipCurrentElement();
        }
      else if(m_qxmlStreamReader.name().toString() == "stats")
        {
          while(m_qxmlStreamReader.readNextStartElement())
            {

              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "stat")
                {
                  /*
                  <stat key="0" value="48.5"/>
                  */
                  // qDebug() << __FILE__ << " " << __FUNCTION__ << " "
                  // << __LINE__;

                  IdentificationEngineStatistics type =
                    static_cast<IdentificationEngineStatistics>(
                      m_qxmlStreamReader.attributes().value("key").toUInt());
                  sp_current_identification_source.get()
                    ->setIdentificationEngineStatistics(
                      type,
                      string2QVariant(m_qxmlStreamReader.attributes()
                                        .value("value")
                                        .toString()));
                  m_qxmlStreamReader.skipCurrentElement();
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }

          m_qxmlStreamReader.skipCurrentElement();
        }
    }
  else
    {
      // m_qxmlStreamReader.skipCurrentElement();
    }
}


void
XpipReader::readProteinList()
{
  /*

    <protein_list>
        <protein fasta_id="fastaa0" acc="AC147602.5_FGP004"
    description="seq=translation; coord=3:178846540..178848005:-1;
    parent_transcript=AC147602.5_FGT004; parent_gene=AC147602.5_FG004"
    is_decoy="false" is_contaminant="false">
            <sequence>MEIVATRSPACCAAVSFSQSYRPKASRPPTTFYGESVRVNTARPLSARRQSKAASRAALSARCEIGDSLEEFLTKATPDKNLIRLLICMGEAMRTIAFKVRTASCGGTACVNSFGDEQLAVDMLANKLLFEALEYSHVCKYACSEEVPELQDMGGPVEGS</sequence>
        </protein>
*/

  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "protein_list")
        {
          while(readProtein())
            {
            }
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

bool
XpipReader::readProtein()
{
  if((m_countProteins % 1000) == 0)
    {
      if(mp_monitor->shouldIstop())
        {
          throw pappso::ExceptionInterrupted(
            QObject::tr("XPIP file reading interrupted by the user"));
        }
    }
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "protein")
        {
          // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
          mp_monitor->count();
          m_countProteins++;
          m_countTotal++;
          /*
           *  <protein fasta_id="fastaa0" acc="AC149475.2_FGP003"
           description="seq=translation; coord=9:152490486..152495067:-1;
           parent_transcript=AC149475.2_FGT003; parent_gene=AC149475.2_FG003"
           is_decoy="false" is_contaminant="false">
                  <sequence>MFLTRTEYDRGVNTFSPEGRLFQVEYAIEAIKLGSTAIGLKTKDGVVLAVEKRVTSPLLEPSSVEKIMEIDEHIGCAMSGLIADARTLVEHARVETQNHRFSYGEPMTVESSTQAICDLALRFGEGDEESMSRPFGVSLLIAGHDENGPSLYYTDPSGTFWQCNAKAIGSGSEGADSSLQEQYNKELALEEAETIALSILKQVMEEKVTPNNVDIAKVAPKYHLYTPAEVEAVIARL</sequence>
              </protein>
                    */
          ProteinXtpSp sp_current_protein = ProteinXtp().makeProteinXtpSp();

          auto fasta_it = m_mapFastaFiles.find(
            m_qxmlStreamReader.attributes().value("fasta_id").toString());
          if(fasta_it == m_mapFastaFiles.end())
            {
              m_qxmlStreamReader.raiseError(
                QObject::tr("ERROR fasta_id %1 not found")
                  .arg(m_qxmlStreamReader.attributes().value("fasta_id")));
            }
          // qDebug() << "startElement_protein fastaid=" <<
          // attributes.value("fasta_id");
          sp_current_protein.get()->setFastaFileP(fasta_it->second.get());
          sp_current_protein.get()->setAccession(
            m_qxmlStreamReader.attributes().value("acc").toString());

          // qDebug() << "startElement_protein acc=" << attributes.value("acc");
          // qDebug() << "startElement_protein description=" <<
          // attributes.value("description");
          sp_current_protein.get()->setDescription(
            m_qxmlStreamReader.attributes().value("description").toString());
          sp_current_protein.get()->setIsContaminant(false);
          if(m_qxmlStreamReader.attributes()
               .value("is_contaminant")
               .toString()
               .simplified()
               .toLower() == "true")
            {
              sp_current_protein.get()->setIsContaminant(true);
            }
          // qDebug() << "startElement_protein iscontaminant";
          sp_current_protein.get()->setIsDecoy(false);
          if(m_qxmlStreamReader.attributes()
               .value("is_decoy")
               .toString()
               .simplified()
               .toLower() == "true")
            {
              sp_current_protein.get()->setIsDecoy(true);
            }
          // qDebug() << "startElement_protein isdecoy";
          if(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "sequence")
                {
                  sp_current_protein.get()->setSequence(
                    m_qxmlStreamReader.readElementText());
                }
            }

          sp_current_protein =
            mp_project->getProteinStore().getInstance(sp_current_protein);
          m_mapProteins.insert(std::pair<QString, ProteinXtpSp>(
            sp_current_protein.get()->getAccession(), sp_current_protein));

          while(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "dbxref")
                {
                  //<dbxref acc="A2A5Y0" database="3"/>
                  DbXref xref;
                  xref.accession =
                    m_qxmlStreamReader.attributes().value("acc").toString();
                  xref.database = static_cast<ExternalDatabase>(
                    m_qxmlStreamReader.attributes().value("database").toUInt());

                  sp_current_protein.get()->getDbxrefList().push_back(xref);
                  m_qxmlStreamReader.skipCurrentElement();
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }

      return true;
    }
  return false;
}

void
XpipReader::readPeptideList()
{
  /*
<peptide_list>

        <label_method id="dimethyl">
            <label_list>
                <label id="light">
                    <label_modification at="Nter" mod="MOD:00429"/>
                    <label_modification at="K" mod="MOD:00429"/>
                </label>
                <label id="inter">
                    <label_modification at="Nter" mod="MOD:00552"/>
                    <label_modification at="K" mod="MOD:00552"/>
                </label>
                <label id="heavy">
                    <label_modification at="Nter" mod="MOD:00638"/>
                    <label_modification at="K" mod="MOD:00638"/>
                </label>
            </label_list>
        </label_method>
        <modification_list>
            <modification id="moda1" mod="MOD:00408"/>
            <modification id="moda2" mod="MOD:01160"/>
            <modification id="moda3"
mod="internal:Cter_hydrolytic_cleavage_HO"/> <modification id="moda4"
mod="MOD:00397"/> <modification id="moda5" mod="MOD:00704"/> <modification
id="moda6" mod="MOD:00719"/> <modification id="moda7"
mod="internal:Nter_hydrolytic_cleavage_H"/>
        </modification_list>
        <peptide id="pa1" seq="QLFHPEQLISGK">
            <mod ref="moda2" position="0" aa="Q"/>
        </peptide>
*/

  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "peptide_list")
        {
          readLabelMethodModificationList();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
  qDebug() << m_qxmlStreamReader.name();
}
void
XpipReader::readLabelMethodModificationList()
{

  qDebug() << "should be peptide list" << m_qxmlStreamReader.name();
  while(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "label_method")
        { //<label_method id="dimethyl">

          LabelingMethod method(m_qxmlStreamReader.attributes()
                                  .value("id")
                                  .toString()
                                  .simplified());
          msp_labelingMethod = method.makeLabelingMethodSp();
          mp_project->setLabelingMethodSp(msp_labelingMethod);

          if(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "label_list")
                {
                  m_qxmlStreamReader.skipCurrentElement();

                  while(readLabel(msp_labelingMethod))
                    {
                    }
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
          else
            {
              m_isI2masschroqXpip = false;
              m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
              m_qxmlStreamReader.skipCurrentElement();
            }
        }

      else if(m_qxmlStreamReader.name().toString() == "modification_list")
        {
          while(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name().toString() == "modification")
                {
                  pappso::AaModificationP mod =
                    pappso::AaModification::getInstance(
                      m_qxmlStreamReader.attributes()
                        .value("mod")
                        .toString()
                        .simplified());
                  m_mapModifs.insert(
                    std::pair<QString, pappso::AaModificationP>(
                      m_qxmlStreamReader.attributes()
                        .value("id")
                        .toString()
                        .simplified(),
                      mod));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }
      else
        {

          if(readPeptide())
            {
            }
        }
    }
}

bool
XpipReader::readPeptide()
{

  if((m_countPeptides % 1000) == 0)
    {
      if(mp_monitor->shouldIstop())
        {
          throw pappso::ExceptionInterrupted(
            QObject::tr("XPIP file reading interrupted by the user"));
        }
    }
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.name().toString() == "peptide")
    {
      // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
      mp_monitor->count();
      m_countPeptides++;
      m_countTotal++;
      /*
       *  <peptide id="pa1" seq="QLFHPEQLISGK">
        <mod ref="moda2" position="0" aa="Q"/>
    </peptide>
                */

      QString current_id =
        m_qxmlStreamReader.attributes().value("id").toString().simplified();
      PeptideXtpSp peptide_sp;
      QString seq =
        m_qxmlStreamReader.attributes().value("seq").toString().simplified();
      if(seq.isEmpty())
        {
          QString proforma =
            m_qxmlStreamReader.attributes().value("proforma").toString();
          if(proforma.isEmpty())
            { // missing proforma sequence
              throw pappso::ExceptionNotFound(
                QObject::tr("ProForma peptide not found in peptide %1")
                  .arg(current_id));
            }
          else
            {
              peptide_sp = std::make_shared<PeptideXtp>(
                *pappso::PeptideProFormaParser::parseString(proforma).get());
            }
        }
      else
        {
          peptide_sp = std::make_shared<PeptideXtp>(seq);
        }
      QString label =
        m_qxmlStreamReader.attributes().value("label_id").toString();

      QString nter_mod =
        m_qxmlStreamReader.attributes().value("nter_mod").toString();
      if(!nter_mod.isEmpty())
        {
          peptide_sp.get()->setNterModification(
            m_mapModifs[nter_mod.simplified()]);
        }

      QString cter_mod =
        m_qxmlStreamReader.attributes().value("cter_mod").toString();
      if(!cter_mod.isEmpty())
        {
          peptide_sp.get()->setCterModification(
            m_mapModifs[cter_mod.simplified()]);
        }

      while(m_qxmlStreamReader.readNextStartElement())
        {
          qDebug() << m_qxmlStreamReader.name();
          if(m_qxmlStreamReader.name() == QString("mod"))
            {
              pappso::AaModificationP modif =
                m_mapModifs[m_qxmlStreamReader.attributes()
                              .value("ref")
                              .toString()
                              .simplified()];
              unsigned int position =
                m_qxmlStreamReader.attributes().value("position").toUInt();
              peptide_sp.get()->addAaModification(modif, position);


              m_qxmlStreamReader.skipCurrentElement();
            }
          else
            {
              m_isI2masschroqXpip = false;
              m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
              m_qxmlStreamReader.skipCurrentElement();
            }
        }


      peptide_sp = mp_project->getPeptideStore().getInstance(peptide_sp);
      m_mapPeptides.insert(
        std::pair<QString, PeptideXtpSp>(current_id, peptide_sp));

      if(msp_labelingMethod.get() != nullptr)
        {
          //<peptide id="pa1" seq="AEYAVDHNNGTGALFFR" label_id="heavy">
          peptide_sp.get()->applyLabelingMethod(msp_labelingMethod);
        }
    }

  else
    {
      m_isI2masschroqXpip = false;
      m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
      m_qxmlStreamReader.skipCurrentElement();
    }
  return true;
}


bool
XpipReader::readLabel(LabelingMethodSp labelingMethodSp [[maybe_unused]])
{
  /*
   * <label id="light">
                      <label_modification at="Nter" mod="MOD:00429"/>
                      <label_modification at="K" mod="MOD:00429"/>
                  </label>
                  */
  qDebug() << m_qxmlStreamReader.name();
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name() == QString("label"))
        {
          // TODO
          while(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name() == QString("label_modification"))
                {
                  // TODO
                  m_qxmlStreamReader.skipCurrentElement();
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }

      return true;
    }
  return false;
}


bool
XpipReader::readIdentificationGroup()
{
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name().toString() == "identification_group")
        {

          IdentificationGroup *identification_group_p =
            mp_project->newIdentificationGroup();
          // TODO
          while(m_qxmlStreamReader.readNextStartElement())
            {
              qDebug() << m_qxmlStreamReader.name();
              //<peptide_evidence_list ident_source_id="identa0">
              if(m_qxmlStreamReader.name() == QString("peptide_evidence_list"))
                {

                  IdentificationDataSourceSp identification_source_sp =
                    m_mapIdentSources.at(m_qxmlStreamReader.attributes()
                                           .value("ident_source_id")
                                           .toString()
                                           .simplified());
                  identification_group_p->addIdentificationDataSourceP(
                    identification_source_sp.get());

                  //
                  while(readPeptideEvidence(identification_source_sp))
                    {
                    }


                  identification_source_sp.get()
                    ->getPeptideEvidenceStore()
                    .clearMap();

                  // m_qxmlStreamReader.skipCurrentElement();
                }
              else if(m_qxmlStreamReader.name() ==
                      QString("protein_match_list"))
                {
                  //<protein_match_list>
                  while(readProteinMatch(identification_group_p))
                    {
                    }

                  // m_qxmlStreamReader.skipCurrentElement();
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }

      return true;
    }
  return false;
}

bool
XpipReader::readPeptideEvidence(
  IdentificationDataSourceSp identification_source_sp)
{

  if((m_countPeptideEvidences % 1000) == 0)
    {
      if(mp_monitor->shouldIstop())
        {
          throw pappso::ExceptionInterrupted(
            QObject::tr("XPIP file reading interrupted by the user"));
        }
    }
  if(m_qxmlStreamReader.readNextStartElement())
    {
      // qDebug() << m_qxmlStreamReader.name();
      //<peptide_evidence id="pea1" peptide_id="pe11189" scan="1976"
      // rt="667.022" eng="1" evalue="0.00066" exp_mass="1119.522195" charge="2"
      // checked="true">

      if(m_qxmlStreamReader.name() == QString("peptide_evidence"))
        {


          m_countPeptideEvidences++;
          m_countTotal++;
          mp_monitor->count();


          PeptideEvidence *p_peptide_evidence = nullptr;

          if(!m_qxmlStreamReader.attributes().value("scan").isEmpty())
            {
              p_peptide_evidence = new PeptideEvidence(
                identification_source_sp.get()->getMsRunSp().get(),
                m_qxmlStreamReader.attributes().value("scan").toUInt(),
                false);
            }
          if(!m_qxmlStreamReader.attributes().value("idx").isEmpty())
            {
              p_peptide_evidence = new PeptideEvidence(
                identification_source_sp.get()->getMsRunSp().get(),
                m_qxmlStreamReader.attributes().value("idx").toUInt(),
                true);
            }
          if(p_peptide_evidence == nullptr)
            {
              throw pappso::PappsoException(
                QObject::tr("peptide must define 'scan' or 'idx' attribute"));
            }

          p_peptide_evidence->setIdentificationDataSource(
            identification_source_sp.get());

          p_peptide_evidence->setChecked(false);
          if(m_qxmlStreamReader.attributes()
               .value("checked")
               .toString()
               .simplified()
               .toLower() == "true")
            {
              p_peptide_evidence->setChecked(true);
            }
          p_peptide_evidence->setCharge(
            m_qxmlStreamReader.attributes().value("charge").toUInt());
          if(!m_qxmlStreamReader.attributes().value("eng").isEmpty())
            {
              p_peptide_evidence->setIdentificationEngine(
                static_cast<IdentificationEngine>(
                  m_qxmlStreamReader.attributes().value("eng").toUInt()));
            }
          p_peptide_evidence->setRetentionTime(
            m_qxmlStreamReader.attributes().value("rt").toDouble());
          p_peptide_evidence->setEvalue(
            m_qxmlStreamReader.attributes().value("evalue").toDouble());
          p_peptide_evidence->setExperimentalMass(
            m_qxmlStreamReader.attributes().value("exp_mass").toDouble());
          p_peptide_evidence->setPeptideXtpSp(
            m_mapPeptides.at(m_qxmlStreamReader.attributes()
                               .value("peptide_id")
                               .toString()
                               .simplified()));

          PeptideEvidenceSp sp_current_peptide_evidence =
            identification_source_sp.get()
              ->getPeptideEvidenceStore()
              .recordInstance(p_peptide_evidence);
          delete p_peptide_evidence;
          p_peptide_evidence = nullptr;
          m_mapPeptideEvidences.insert(std::pair<QString, PeptideEvidenceSp>(
            m_qxmlStreamReader.attributes().value("id").toString().simplified(),
            sp_current_peptide_evidence));


          readParams(sp_current_peptide_evidence);

          // m_qxmlStreamReader.skipCurrentElement();
          return true;
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
  return false;
}

bool
XpipReader::readProteinMatch(IdentificationGroup *identification_group_p)
{
  if((m_countProteinMatches % 1000) == 0)
    {
      if(mp_monitor->shouldIstop())
        {
          throw pappso::ExceptionInterrupted(
            QObject::tr("XPIP file reading interrupted by the user"));
        }
    }
  if(m_qxmlStreamReader.readNextStartElement())
    {
      //<protein_match acc="GRMZM2G083841_P01" checked="true">
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name() == QString("protein_match"))
        {
          ProteinMatch *p_protein_match = new ProteinMatch();


          p_protein_match->setProteinXtpSp(
            m_mapProteins.at(m_qxmlStreamReader.attributes()
                               .value("acc")
                               .toString()
                               .simplified()));
          p_protein_match->setChecked(false);
          if(m_qxmlStreamReader.attributes()
               .value("checked")
               .toString()
               .simplified()
               .toLower() == "true")
            {
              p_protein_match->setChecked(true);
            }

          // peptide_match
          while(m_qxmlStreamReader.readNextStartElement())
            {
              //<peptide_match peptide_evidence_id="pef143066" start="679"/>
              // qDebug() << m_qxmlStreamReader.name();
              if(m_qxmlStreamReader.name() == QString("peptide_match"))
                {
                  PeptideMatch peptide_match;
                  peptide_match.setPeptideEvidenceSp(
                    m_mapPeptideEvidences.at(m_qxmlStreamReader.attributes()
                                               .value("peptide_evidence_id")
                                               .toString()
                                               .simplified()));
                  peptide_match.setStart(
                    m_qxmlStreamReader.attributes().value("start").toUInt());
                  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
                  // __LINE__;
                  p_protein_match->addPeptideMatch(peptide_match);
                  m_qxmlStreamReader.skipCurrentElement();
                }
              else if(m_qxmlStreamReader.name() == QString("params"))
                {
                  readParams(p_protein_match);
                }
              else
                {
                  m_isI2masschroqXpip = false;
                  m_qxmlStreamReader.raiseError(
                    QObject::tr("Not an XPIP file"));
                  m_qxmlStreamReader.skipCurrentElement();
                }
            }


          m_countProteinMatches++;
          m_countTotal++;
          identification_group_p->addProteinMatch(p_protein_match);

          qDebug() << p_protein_match->getPeptideMatchList().size();
          mp_monitor->count();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }

      return true;
    }
  return false;
}

void
XpipReader::readAlignmentParams()
{
  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name() == QString("alignment_params"))
        {
          MasschroqFileParameters *p_masschroq_file_params =
            mp_project->getMasschroqFileParametersSp().get();
          p_masschroq_file_params->m_alignmentMethod.setMs2TendencyWindow(
            m_qxmlStreamReader.attributes().value("ms2_tendency").toInt());
          p_masschroq_file_params->m_alignmentMethod.setMs2SmoothingWindow(
            m_qxmlStreamReader.attributes().value("ms2_smoothing").toInt());
          p_masschroq_file_params->m_alignmentMethod.setMs1SmoothingWindow(
            m_qxmlStreamReader.attributes().value("ms1_smoothing").toInt());
          m_qxmlStreamReader.skipCurrentElement();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readMasschroqParams(MsRunAlignmentGroupSp sp_alignment_group)
{

  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name() == QString("masschroq_params"))
        {
          MasschroqFileParameters *p_masschroq_file_params =
            mp_project->getMasschroqFileParametersSp().get();
          sp_alignment_group->setMassChroqmlPath(
            m_qxmlStreamReader.attributes().value("masschroqml").toString());
          if(QFileInfo(
               m_qxmlStreamReader.attributes().value("result").toString())
               .suffix() == "ods")
            {
              p_masschroq_file_params->result_file_format =
                TableFileFormat::ods;
            }
          else
            {
              p_masschroq_file_params->result_file_format =
                TableFileFormat::tsv;
            }

          m_qxmlStreamReader.skipCurrentElement();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}

void
XpipReader::readQuantiParams()
{

  if(m_qxmlStreamReader.readNextStartElement())
    {
      qDebug() << m_qxmlStreamReader.name();
      if(m_qxmlStreamReader.name() == QString("quanti_params"))
        {

          MasschroqFileParameters *p_masschroq_file_params =
            mp_project->getMasschroqFileParametersSp().get();
          p_masschroq_file_params->m_quantificationMethod
            .setXicExtractionLowerPrecisionPtr(
              pappso::PrecisionFactory::fromString(
                m_qxmlStreamReader.attributes().value("xic_range").toString()));
          p_masschroq_file_params->m_quantificationMethod
            .setXicExtractionUpperPrecisionPtr(
              pappso::PrecisionFactory::fromString(
                m_qxmlStreamReader.attributes().value("xic_range").toString()));
          if(m_qxmlStreamReader.attributes().value("xic_method").toInt() == 0)
            {
              p_masschroq_file_params->m_quantificationMethod
                .setXicExtractMethod(pappso::Enums::XicExtractMethod::max);
            }
          else
            {
              p_masschroq_file_params->m_quantificationMethod
                .setXicExtractMethod(pappso::Enums::XicExtractMethod::sum);
            }


          std::shared_ptr<pappso::TraceDetectionZivy> sp_detection_zivy =
            std::make_shared<pappso::TraceDetectionZivy>(
              m_qxmlStreamReader.attributes().value("smoothing").toInt(),
              m_qxmlStreamReader.attributes().value("minmax_half").toInt(),
              m_qxmlStreamReader.attributes().value("maxmin_half").toInt(),
              m_qxmlStreamReader.attributes().value("minmax_thre").toDouble(),
              m_qxmlStreamReader.attributes().value("maxmin_thre").toDouble());
          p_masschroq_file_params->m_quantificationMethod
            .setTraceDetectionInterfaceCstSPtr(sp_detection_zivy);
          m_qxmlStreamReader.skipCurrentElement();
        }

      else
        {
          m_isI2masschroqXpip = false;
          m_qxmlStreamReader.raiseError(QObject::tr("Not an XPIP file"));
          m_qxmlStreamReader.skipCurrentElement();
        }
    }
}
