
/*******************************************************************************
 * Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.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/>.
 *
 * Contributors:
 *     Olivier Langella <olivier.langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "peptidetablemodel.h"

#include <QDebug>
#include <QColor>
#include <QSize>
#include "peptidelistwindow.h"
#include <pappsomspp/core/grouping/grppeptide.h>
#include <pappsomspp/core/pappsoexception.h>
#include <pappsomspp/core/psm/deepprot/deepprotenum.h>
#include "../../../core/labeling/label.h"
#include "../../../utils/utils.h"
#include <pappsomspp/core/exception/exceptionnotfound.h>


std::vector<PeptideListColumn> PeptideTableModel::m_columnOrder = {

  PeptideListColumn::checked,
  PeptideListColumn::peptide_grouping_id, ///< manual checked
  PeptideListColumn::engine,
  PeptideListColumn::sample,
  PeptideListColumn::scan,
  PeptideListColumn::spectrum_index, ///< spectrum index
  PeptideListColumn::rtmin,
  PeptideListColumn::rt,
  PeptideListColumn::ion_mobility_begin,
  PeptideListColumn::ion_mobility_end,
  PeptideListColumn::collision_energy,
  PeptideListColumn::charge,
  PeptideListColumn::experimental_mz,
  PeptideListColumn::sequence_nter,
  PeptideListColumn::sequence,
  PeptideListColumn::sequence_cter,
  PeptideListColumn::chemical_formula,
  PeptideListColumn::modifs,
  PeptideListColumn::label,
  PeptideListColumn::start,
  PeptideListColumn::length,
  PeptideListColumn::used,
  PeptideListColumn::subgroups,
  PeptideListColumn::Evalue,
  PeptideListColumn::svmprob,
  PeptideListColumn::qvalue,
  PeptideListColumn::experimental_mhplus,
  PeptideListColumn::theoretical_mhplus,
  PeptideListColumn::delta_mhplus,
  PeptideListColumn::delta_ppm,


  PeptideListColumn::peptide_prophet_probability, ///< no PSI MS description
  PeptideListColumn::peptide_inter_prophet_probability, ///< no PSI MS
                                                        ///< description
  PeptideListColumn::tandem_hyperscore, ///< X!Tandem hyperscore MS:1001331
  PeptideListColumn::mascot_score, ///< PSI-MS MS:1001171 mascot:score 56.16
  PeptideListColumn::mascot_expectation_value, ///< PSI-MS MS:1001172
                                               ///< mascot:expectation
                                               ///< value 2.42102904673618e-006
  PeptideListColumn::omssa_evalue, ///< MS:1001328  "OMSSA E-value." [PSI:PI]
  PeptideListColumn::omssa_pvalue, ///< MS:1001329  "OMSSA p-value." [PSI:PI]
  PeptideListColumn::msgfplus_raw, ///< MS:1002049  "MS-GF raw score." [PSI:PI]
  PeptideListColumn::msgfplus_denovo, ///< MS:1002050  "MS-GF de novo score."
                                      ///< [PSI:PI]
  PeptideListColumn::msgfplus_energy, ///< MS:1002051  "MS-GF energy score."
                                      ///< [PSI:PI]
  PeptideListColumn::msgfplus_SpecEValue, ///< MS:1002052  "MS-GF spectral
                                          ///< E-value." [PSI:PI]
  PeptideListColumn::msgfplus_EValue, ///< MS:1002053  "MS-GF E-value." [PSI:PI]
  PeptideListColumn::msgfplus_isotope_error, ///< MS:1002053  "MS-GF E-value."
                                             ///< [PSI:PI]
  PeptideListColumn::comet_xcorr,   ///< MS:1002252  "The Comet result 'XCorr'."
                                    ///< [PSI:PI]
  PeptideListColumn::comet_deltacn, ///< MS:1002253  "The Comet result
                                    ///< 'DeltaCn'." [PSI:PI]
  PeptideListColumn::comet_deltacnstar, ///< MS:1002254  "The Comet result
                                        ///< 'DeltaCnStar'." [PSI:PI]
  PeptideListColumn::comet_spscore,     ///< MS:1002255  "The Comet result
                                        ///< 'SpScore'." [PSI:PI]
  PeptideListColumn::comet_sprank, ///< MS:1002256  "The Comet result 'SpRank'."
                                   ///< [PSI:PI]
  PeptideListColumn::comet_expectation_value, ///< MS:1002257  "The Comet result
                                              ///< 'Expectation value'."
                                              ///< [PSI:PI]
  PeptideListColumn::deepprot_original_count, ///< number of matched peaks
                                              ///< before specfit
  PeptideListColumn::deepprot_fitted_count,   ///< number of matched peaks after
                                              ///< specfit
  PeptideListColumn::deepprot_match_type,     ///< DeepProt spectrum match type
  PeptideListColumn::deepprot_status,         ///< DeepProt PSM status
  PeptideListColumn::deepprot_mass_delta,     ///< DeepProt mass delta
  PeptideListColumn::deepprot_delta_positions,
  PeptideListColumn::sage_isotope_error,
  PeptideListColumn::sage_sage_discriminant_score,
  PeptideListColumn::sage_posterior_error,
  PeptideListColumn::sage_spectrum_q,
  PeptideListColumn::sage_peptide_q,
  PeptideListColumn::sage_predicted_rt};


PeptideTableModel::PeptideTableModel(PeptideListWindow *parent)
  : QAbstractTableModel(parent)
{
  _p_peptide_list_window = parent;
  // ui->tableView->show();
  // QModelIndex topLeft = createIndex(0,0);
  // emit a signal to make the view reread identified data
  // emit dataChanged(topLeft, topLeft);
}


void
PeptideTableModel::setProteinMatch(ProteinMatch *p_protein_match)
{
  qDebug() << "begin ";

  beginResetModel();
  _p_protein_match = p_protein_match;
  endResetModel();
  // QModelIndex topLeft = createIndex(0,0);
  // QModelIndex bottomRight = createIndex(rowCount(),columnCount());

  _engine_columns_to_display.clear();
  bool first = true;
  for(auto &&peptide_match : _p_protein_match->getPeptideMatchList())
    {
      if(first)
        {
          QVariant var = peptide_match.getPeptideEvidence()->getParam(
            PeptideEvidenceParam::peptide_prophet_probability);
          if(!var.isNull())
            {
              _engine_columns_to_display.insert(
                PeptideListColumn::peptide_prophet_probability);
            }
          var = peptide_match.getPeptideEvidence()->getParam(
            PeptideEvidenceParam::peptide_inter_prophet_probability);
          if(!var.isNull())
            {
              _engine_columns_to_display.insert(
                PeptideListColumn::peptide_inter_prophet_probability);
            }
          first = false;
        }
      IdentificationEngine engine =
        peptide_match.getPeptideEvidence()->getIdentificationEngine();
      if(engine == IdentificationEngine::XTandem)
        {
          _engine_columns_to_display.insert(
            PeptideListColumn::tandem_hyperscore);
        }
      else if(engine == IdentificationEngine::mascot)
        {
          _engine_columns_to_display.insert(PeptideListColumn::mascot_score);
          _engine_columns_to_display.insert(
            PeptideListColumn::mascot_expectation_value);
        }
      else if(engine == IdentificationEngine::OMSSA)
        {
          _engine_columns_to_display.insert(PeptideListColumn::omssa_evalue);
          _engine_columns_to_display.insert(PeptideListColumn::omssa_pvalue);
        }
      else if(engine == IdentificationEngine::MSGFplus)
        {
          _engine_columns_to_display.insert(PeptideListColumn::msgfplus_raw);
          _engine_columns_to_display.insert(PeptideListColumn::msgfplus_denovo);
          _engine_columns_to_display.insert(PeptideListColumn::msgfplus_energy);
          _engine_columns_to_display.insert(
            PeptideListColumn::msgfplus_SpecEValue);
          _engine_columns_to_display.insert(PeptideListColumn::msgfplus_EValue);
          _engine_columns_to_display.insert(
            PeptideListColumn::msgfplus_isotope_error);
        }
      else if(engine == IdentificationEngine::Comet)
        {
          _engine_columns_to_display.insert(PeptideListColumn::comet_deltacn);
          _engine_columns_to_display.insert(
            PeptideListColumn::comet_deltacnstar);
          _engine_columns_to_display.insert(
            PeptideListColumn::comet_expectation_value);
          _engine_columns_to_display.insert(PeptideListColumn::comet_sprank);
          _engine_columns_to_display.insert(PeptideListColumn::comet_spscore);
          _engine_columns_to_display.insert(PeptideListColumn::comet_xcorr);
        }
      else if(engine == IdentificationEngine::SpecOMS)
        {
          _engine_columns_to_display.insert(
            PeptideListColumn::deepprot_original_count);
          _engine_columns_to_display.insert(
            PeptideListColumn::deepprot_fitted_count);
          _engine_columns_to_display.insert(
            PeptideListColumn::deepprot_mass_delta);
          _engine_columns_to_display.insert(
            PeptideListColumn::deepprot_delta_positions);
          _engine_columns_to_display.insert(
            PeptideListColumn::deepprot_match_type);
          _engine_columns_to_display.insert(PeptideListColumn::deepprot_status);
        }
      else if(engine == IdentificationEngine::sage)
        {
          _engine_columns_to_display.insert(
            PeptideListColumn::sage_isotope_error);
          _engine_columns_to_display.insert(PeptideListColumn::sage_peptide_q);
          _engine_columns_to_display.insert(
            PeptideListColumn::sage_posterior_error);
          _engine_columns_to_display.insert(
            PeptideListColumn::sage_predicted_rt);
          _engine_columns_to_display.insert(
            PeptideListColumn::sage_sage_discriminant_score);
          _engine_columns_to_display.insert(PeptideListColumn::sage_spectrum_q);
        }
    }

  qDebug() << _engine_columns_to_display.size();
  _p_peptide_list_window->resizeColumnsToContents();
  // emit dataChanged(topLeft, topLeft);
  // emit headerDataChanged(Qt::Horizontal, 0,33);
  emit layoutAboutToBeChanged();
  emit layoutChanged();
  qDebug() << "PeptideTableModel::setProteinMatch end ";
}

ProteinMatch *
PeptideTableModel::getProteinMatch()
{
  return _p_protein_match;
}
int
PeptideTableModel::rowCount(const QModelIndex &parent [[maybe_unused]]) const
{
  if(_p_protein_match != nullptr)
    {
      // qDebug() << "PeptideTableModel::rowCount(const QModelIndex &parent ) "
      // << _p_protein_match->getPeptideMatchList().size();
      return (int)_p_protein_match->getPeptideMatchList().size();
    }
  return 0;
}
int
PeptideTableModel::columnCount(const QModelIndex &parent [[maybe_unused]]) const
{
  return (std::int8_t)PeptideListColumn::last;
}
QVariant
PeptideTableModel::headerData(int section,
                              Qt::Orientation orientation,
                              int role) const
{
  if(orientation == Qt::Horizontal)
    {
      switch(role)
        {
          case Qt::DisplayRole:
            return QVariant(getTitle(getPeptideListColumn(section)));
            break;
          case Qt::ToolTipRole:
            return QVariant(getDescription(getPeptideListColumn(section)));
            break;
        }
    }
  // if
  // (_p_peptide_list_window->getProjectWindow()->getProjectP()->getLabelingMethodSp().get()
  // == nullptr) {
  return QVariant();
}
QVariant
PeptideTableModel::data(const QModelIndex &index, int role) const
{
  // generate a log message when this method gets called
  int row                  = index.row();
  PeptideListColumn column = getPeptideListColumn(index.column());
  // qDebug() << QString("row %1, col%2, role %3")
  //         .arg(row).arg(col).arg(role);

  pappso::QualifiedMassSpectrum mass_spectrum;

  switch(role)
    {
      case Qt::CheckStateRole:

        if(column == PeptideListColumn::checked) // add a checkbox to cell(1,0)
          {
            if(_p_protein_match->getPeptideMatchList()
                 .at(row)
                 .getPeptideEvidence()
                 ->isChecked())
              {
                return Qt::Checked;
              }
            else
              {
                return Qt::Unchecked;
              }
          }
        break;
      case Qt::BackgroundRole:
        if(_p_protein_match->getPeptideMatchList()
             .at(row)
             .getPeptideEvidence()
             ->isValid() == false)
          {
            return QVariant(QColor("grey"));
          }
        break;
      case Qt::SizeHintRole:
        // qDebug() << "ProteinTableModel::headerData " <<
        // ProteinTableModel::getColumnWidth(section);
        return QSize(PeptideTableModel::getColumnWidth(column), 30);
        break;
      case Qt::ToolTipRole:
        if(column == PeptideListColumn::sample)
          {
            return QVariant(_p_protein_match->getPeptideMatchList()
                              .at(row)
                              .getPeptideEvidence()
                              ->getIdentificationDataSource()
                              ->getMsRunSp()
                              ->getFileName());
          }
        break;
      case Qt::DisplayRole:
        if(_p_protein_match == nullptr)
          {
          }
        else
          {
            pappso::GrpPeptide *p_grp_peptide;
            const Label *p_label;
            GroupingGroup *p_grp;
            switch(column)
              {
                case PeptideListColumn::checked:
                  return QVariant();
                  break;

                case PeptideListColumn::peptide_grouping_id:
                  p_grp_peptide = _p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getGrpPeptideSp()
                                    .get();
                  if(p_grp_peptide != nullptr)
                    return p_grp_peptide->getGroupingId();
                  return QVariant();
                  break;
                case PeptideListColumn::engine:
                  return Utils::getIdentificationEngineName(
                    _p_protein_match->getPeptideMatchList()
                      .at(row)
                      .getPeptideEvidence()
                      ->getIdentificationEngine());
                  break;
                case PeptideListColumn::sample:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getIdentificationDataSource()
                    ->getSampleName();
                  break;
                case PeptideListColumn::scan:
                  return QVariant(
                    (quint32)_p_protein_match->getPeptideMatchList()
                      .at(row)
                      .getPeptideEvidence()
                      ->getScanNumber());
                  break;
                case PeptideListColumn::spectrum_index:
                  try
                    {
                      return QVariant(
                        (quint32)_p_protein_match->getPeptideMatchList()
                          .at(row)
                          .getPeptideEvidence()
                          ->getSpectrumIndex());
                    }
                  catch(pappso::ExceptionNotFound &notfound)
                    {
                      // no spectrum index
                    }
                  break;
                case PeptideListColumn::rtmin:
                  return QVariant(
                    (qreal)(_p_protein_match->getPeptideMatchList()
                              .at(row)
                              .getPeptideEvidence()
                              ->getRetentionTime() /
                            60));
                  break;
                case PeptideListColumn::rt:
                  return QVariant((qreal)_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getRetentionTime());
                  break;
                case PeptideListColumn::charge:
                  return QVariant(
                    (quint32)_p_protein_match->getPeptideMatchList()
                      .at(row)
                      .getPeptideEvidence()
                      ->getCharge());
                  break;

                case PeptideListColumn::ion_mobility_begin:
                  try
                    {
                      mass_spectrum = _p_protein_match->getPeptideMatchList()
                                        .at(row)
                                        .getPeptideEvidence()
                                        ->getQualifiedMassSpectrum(false);

                      qDebug();
                      return QVariant(mass_spectrum.getParameterValue(
                        pappso::QualifiedMassSpectrumParameter::
                          IonMobOneOverK0Begin));
                    }
                  catch(pappso::ExceptionNotFound &notfound)
                    {
                      // no spectrum index
                    }
                  break;

                case PeptideListColumn::ion_mobility_end:
                  try
                    {
                      mass_spectrum = _p_protein_match->getPeptideMatchList()
                                        .at(row)
                                        .getPeptideEvidence()
                                        ->getQualifiedMassSpectrum(false);

                      qDebug();
                      return QVariant(mass_spectrum.getParameterValue(
                        pappso::QualifiedMassSpectrumParameter::
                          IonMobOneOverK0End));
                    }
                  catch(pappso::ExceptionNotFound &notfound)
                    {
                      // no spectrum index
                    }
                  break;

                case PeptideListColumn::collision_energy:
                  try
                    {
                      mass_spectrum = _p_protein_match->getPeptideMatchList()
                                        .at(row)
                                        .getPeptideEvidence()
                                        ->getQualifiedMassSpectrum(false);

                      qDebug();
                      return QVariant(mass_spectrum.getParameterValue(
                        pappso::QualifiedMassSpectrumParameter::
                          CollisionEnergy));
                    }
                  catch(pappso::ExceptionNotFound &notfound)
                    {
                      // no spectrum index
                    }
                  break;
                case PeptideListColumn::experimental_mz:
                  return QVariant(_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getExperimentalMz());
                  break;
                case PeptideListColumn::sequence_nter:

                  return _p_protein_match->getFlankingNterRegion(
                    _p_protein_match->getPeptideMatchList().at(row), 1);
                  break;
                case PeptideListColumn::sequence:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getPeptideXtpSp()
                    .get()
                    ->getSequence();
                  break;

                case PeptideListColumn::sequence_cter:

                  return _p_protein_match->getFlankingCterRegion(
                    _p_protein_match->getPeptideMatchList().at(row), 1);
                  break;
                case PeptideListColumn::chemical_formula:
                  try
                    {
                      auto peptide_evidence =
                        _p_protein_match->getPeptideMatchList()
                          .at(row)
                          .getPeptideEvidence();
                      return peptide_evidence->getPeptideXtpSp()
                        .get()
                        ->getFormula(peptide_evidence->getCharge());
                    }
                  catch(pappso::ExceptionNotFound &notfound)
                    {
                    }
                  break;
                case PeptideListColumn::modifs:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getPeptideXtpSp()
                    .get()
                    ->getModifString();
                  break;
                case PeptideListColumn::label:
                  p_label = _p_protein_match->getPeptideMatchList()
                              .at(row)
                              .getPeptideEvidence()
                              ->getPeptideXtpSp()
                              .get()
                              ->getLabel();
                  if(p_label != nullptr)
                    {
                      return QVariant(p_label->getXmlId());
                    }
                  else
                    {
                      return QVariant();
                    }
                  break;
                case PeptideListColumn::start:
                  return QVariant(
                    (quint32)_p_protein_match->getPeptideMatchList()
                      .at(row)
                      .getStart() +
                    1);
                  break;
                case PeptideListColumn::length:
                  return QVariant(
                    (quint32)_p_protein_match->getPeptideMatchList()
                      .at(row)
                      .getPeptideEvidence()
                      ->getPeptideXtpSp()
                      .get()
                      ->size());
                  break;
                case PeptideListColumn::used:
                  p_grp = _p_protein_match->getGroupingGroupSp().get();
                  if(p_grp != nullptr)
                    return QVariant((qreal)p_grp->countSubgroupPresence(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()));
                  return QVariant();
                  break;
                case PeptideListColumn::subgroups:
                  p_grp = _p_protein_match->getGroupingGroupSp().get();
                  if(p_grp != nullptr)
                    return QVariant(p_grp
                                      ->getSubgroupIdList(
                                        _p_protein_match->getPeptideMatchList()
                                          .at(row)
                                          .getPeptideEvidence())
                                      .join(" "));
                  return QVariant();
                  break;
                case PeptideListColumn::Evalue:
                  return QVariant((qreal)_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getEvalue());
                  break;
                case PeptideListColumn::svmprob:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::svmProb);
                  break;
                case PeptideListColumn::qvalue:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::pappso_qvalue);
                  break;
                case PeptideListColumn::experimental_mhplus:
                  return QVariant(_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getExperimentalMhplus());
                  break;
                case PeptideListColumn::theoretical_mhplus:
                  return QVariant(_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getPeptideXtpSp()
                                    .get()
                                    ->getMz(1));
                  break;
                case PeptideListColumn::delta_mhplus:
                  return QVariant((qreal)_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getDeltaMass());
                  break;
                case PeptideListColumn::delta_ppm:
                  return QVariant((qreal)_p_protein_match->getPeptideMatchList()
                                    .at(row)
                                    .getPeptideEvidence()
                                    ->getPpmDeltaMass());
                  break;
                case PeptideListColumn::tandem_hyperscore:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::tandem_hyperscore);
                  break;
                case PeptideListColumn::mascot_score:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::mascot_score);
                  break;
                case PeptideListColumn::mascot_expectation_value:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::mascot_expectation_value);
                  break;

                case PeptideListColumn::peptide_prophet_probability:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(
                      PeptideEvidenceParam::peptide_prophet_probability);
                  break;
                case PeptideListColumn::peptide_inter_prophet_probability:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(
                      PeptideEvidenceParam::peptide_inter_prophet_probability);
                  break;
                case PeptideListColumn::omssa_evalue:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::omssa_evalue);
                  break;
                case PeptideListColumn::omssa_pvalue:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::omssa_pvalue);
                  break;
                case PeptideListColumn::msgfplus_denovo:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_denovo);
                  break;
                case PeptideListColumn::msgfplus_energy:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_energy);
                  break;
                case PeptideListColumn::msgfplus_EValue:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_EValue);
                  break;
                case PeptideListColumn::msgfplus_raw:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_raw);
                  break;
                case PeptideListColumn::msgfplus_SpecEValue:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_SpecEValue);
                  break;

                case PeptideListColumn::msgfplus_isotope_error:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::msgfplus_isotope_error);
                  break;
                case PeptideListColumn::comet_xcorr:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_xcorr);
                  break;
                case PeptideListColumn::comet_deltacn:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_deltacn);
                  break;
                case PeptideListColumn::comet_deltacnstar:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_deltacnstar);
                  break;
                case PeptideListColumn::comet_spscore:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_spscore);
                  break;
                case PeptideListColumn::comet_sprank:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_sprank);
                  break;
                case PeptideListColumn::comet_expectation_value:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::comet_expectation_value);
                  break;
                case PeptideListColumn::deepprot_original_count:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::deepprot_original_count);
                  break;

                case PeptideListColumn::deepprot_fitted_count:
                  return _p_protein_match->getPeptideMatchList()
                    .at(row)
                    .getPeptideEvidence()
                    ->getParam(PeptideEvidenceParam::deepprot_fitted_count);
                  break;

                case PeptideListColumn::deepprot_match_type:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::deepprot_match_type));
                    if(param.isNull())
                      return QString();
                    return pappso::DeepProtEnumStr::toString(
                      (pappso::DeepProtMatchType)param.toUInt());
                  }
                  break;


                case PeptideListColumn::deepprot_status:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::
                                     deepprot_peptide_candidate_status));
                    if(param.isNull())
                      return QString();
                    return pappso::DeepProtEnumStr::toString(
                      (pappso::DeepProtPeptideCandidateStatus)param.toUInt());
                  }
                  break;
                case PeptideListColumn::deepprot_mass_delta:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::deepprot_mass_delta));
                    if(param.isNull())
                      return QString();
                    return param.toDouble();
                  }
                  break;


                case PeptideListColumn::deepprot_delta_positions:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(
                          PeptideEvidenceParam::deepprot_delta_positions));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::sage_isotope_error:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::sage_isotope_error));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::sage_peptide_q:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::sage_peptide_q));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::sage_posterior_error:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::sage_posterior_error));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;

                case PeptideListColumn::sage_predicted_rt:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::sage_predicted_rt));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::sage_sage_discriminant_score:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(
                          PeptideEvidenceParam::sage_sage_discriminant_score));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::sage_spectrum_q:
                  {
                    QVariant param(
                      _p_protein_match->getPeptideMatchList()
                        .at(row)
                        .getPeptideEvidence()
                        ->getParam(PeptideEvidenceParam::sage_spectrum_q));
                    if(param.isNull())
                      return QString();
                    return param;
                  }
                  break;
                case PeptideListColumn::last:
                  break;
              }
          }
        return QString();
    }
  return QVariant();
}

void
PeptideTableModel::onPeptideDataChanged()
{
  qDebug() << "begin " << rowCount();
  emit layoutAboutToBeChanged();
  emit layoutChanged();
}


PeptideListColumn
PeptideTableModel::getPeptideListColumn(std::int8_t column)
{
  return m_columnOrder[column];
}

int
PeptideTableModel::getColumnIndex(PeptideListColumn column)
{
  return std::distance(
    m_columnOrder.begin(),
    std::find(m_columnOrder.begin(), m_columnOrder.end(), column));
}


const QString
PeptideTableModel::getTitle(PeptideListColumn column)
{
  qDebug() << " begin ";

  // qDebug() << "PeptideTableModel::getTitle begin " << column;
  switch(column)
    {

      case PeptideListColumn::checked:
        return "Checked";
        break;
      case PeptideListColumn::peptide_grouping_id:
        return "Peptide ID";
        break;
      case PeptideListColumn::engine:
        return "Engine";
        break;
      case PeptideListColumn::sample:
        return "Sample";
        break;
      case PeptideListColumn::scan:
        return "Scan";
        break;
      case PeptideListColumn::spectrum_index:
        return "Index";
        break;
      case PeptideListColumn::rtmin:
        return "RT (min)";
        break;
      case PeptideListColumn::rt:
        return "RT (s)";
        break;
      case PeptideListColumn::ion_mobility_begin:
        return "1/K0 start";
        break;
      case PeptideListColumn::ion_mobility_end:
        return "1/K0 stop";
        break;
      case PeptideListColumn::collision_energy:
        return "Collision energy (eV)";
        break;
      case PeptideListColumn::charge:
        return "Charge";
        break;
      case PeptideListColumn::experimental_mz:
        return "Obs. m/z";
        break;
      case PeptideListColumn::sequence_nter:
        return "N-term";
        break;
      case PeptideListColumn::sequence:
        return "Sequence";
        break;
      case PeptideListColumn::chemical_formula:
        return "Formula";
        break;
      case PeptideListColumn::sequence_cter:
        return "C-term";
        break;
      case PeptideListColumn::modifs:
        return "Modifs";
        break;
      case PeptideListColumn::label:
        return "Label";
        break;
      case PeptideListColumn::start:
        return "Start";
        break;
      case PeptideListColumn::length:
        return "Length";
        break;
      case PeptideListColumn::used:
        return "Used";
        break;
      case PeptideListColumn::subgroups:
        return "Subgroups";
        break;
      case PeptideListColumn::Evalue:
        return "E-value";
        break;
      case PeptideListColumn::svmprob:
        return "SVM prob";
        break;
      case PeptideListColumn::qvalue:
        return "Cumulated FDR";
        break;
      case PeptideListColumn::experimental_mhplus:
        return "Obs. [M+H]+";
        break;
      case PeptideListColumn::theoretical_mhplus:
        return "Theor. [M+H]+";
        break;
      case PeptideListColumn::delta_mhplus:
        return "Delta [M+H]+";
        break;
      case PeptideListColumn::delta_ppm:
        return "Delta (ppm)";
        break;
      case PeptideListColumn::tandem_hyperscore:
        return "HyperScore";
        break;
      case PeptideListColumn::mascot_score:
        return "Mascot score";
        break;
      case PeptideListColumn::mascot_expectation_value:
        return "Mascot E-value";
        break;
      case PeptideListColumn::peptide_prophet_probability:
        return "Prophet prob.";
        break;
      case PeptideListColumn::peptide_inter_prophet_probability:
        return "Inter prophet prob.";
        break;
      case PeptideListColumn::omssa_evalue:
        return "OMSSA E-value";
        break;
      case PeptideListColumn::omssa_pvalue:
        return "OMSSA p-value";
        break;
      case PeptideListColumn::msgfplus_denovo:
        return "MS-GF de novo";
        break;
      case PeptideListColumn::msgfplus_energy:
        return "MS-GF energy";
        break;
      case PeptideListColumn::msgfplus_EValue:
        return "MS-GF E-value";
        break;
      case PeptideListColumn::msgfplus_raw:
        return "MS-GF raw score";
        break;
      case PeptideListColumn::msgfplus_SpecEValue:
        return "MS-GF spectral E-value";
        break;
      case PeptideListColumn::msgfplus_isotope_error:
        return "MS-GF isotope error";
        break;

      case PeptideListColumn::comet_xcorr:
        return "Comet XCorr";
        break;

      case PeptideListColumn::comet_deltacn:
        return "Comet DeltaCn";
        break;
      case PeptideListColumn::comet_deltacnstar:
        return "Comet DeltaCnStar";
        break;
      case PeptideListColumn::comet_spscore:
        return "Comet SpScore";
        break;
      case PeptideListColumn::comet_sprank:
        return "Comet SpRank";
        break;
      case PeptideListColumn::comet_expectation_value:
        return "Comet E-value";
        break;
      case PeptideListColumn::deepprot_original_count:
        return "DeepProt matched peaks";
        break;
      case PeptideListColumn::deepprot_fitted_count:
        return "DeepProt fitted peaks";
        break;

      case PeptideListColumn::deepprot_match_type:
        return "DeepProt match type";
        break;

      case PeptideListColumn::deepprot_status:
        return "DeepProt status";
        break;
      case PeptideListColumn::deepprot_mass_delta:
        return "DeepProt mass delta";
        break;
      case PeptideListColumn::deepprot_delta_positions:
        return "DeepProt mass delta pos.";
        break;
      case PeptideListColumn::sage_isotope_error:
        return "Sage Isotope error";
        break;
      case PeptideListColumn::sage_peptide_q:
        return "Sage peptide Q-value";
        break;
      case PeptideListColumn::sage_posterior_error:
        return "Sage peptide posterior error";
        break;
      case PeptideListColumn::sage_predicted_rt:
        return "Sage predicted rt";
        break;
      case PeptideListColumn::sage_sage_discriminant_score:
        return "Sage discriminant score";
        break;
      case PeptideListColumn::sage_spectrum_q:
        return "Sage spectrum Q-value";
        break;
      case PeptideListColumn::last:
        break;
    }
  return "";
}
const QString
PeptideTableModel::getDescription(PeptideListColumn column)
{
  // qDebug() << "PeptideTableModel::columnCount begin ";

  qDebug() << " column=" << (int)column;
  switch(column)
    {

      case PeptideListColumn::checked:
        return "Manual protein check";
        break;

      case PeptideListColumn::peptide_grouping_id:
        return "Unique peptide identifier within this grouping experiment";
        break;
      case PeptideListColumn::engine:
        return "Search engine";
        break;
      case PeptideListColumn::sample:
        return "MS sample name";
        break;
      case PeptideListColumn::scan:
        return "Scan number";
        break;
      case PeptideListColumn::spectrum_index:
        return "Spectrum index";
        break;
      case PeptideListColumn::rtmin:
        return "Retention time in minutes";
        break;
      case PeptideListColumn::rt:
        return "Retention time in seconds";
        break;
      case PeptideListColumn::ion_mobility_begin:
        return "Ion mobility start (if available)";
        break;
      case PeptideListColumn::ion_mobility_end:
        return "Ion mobility stop (if available)";
        break;
      case PeptideListColumn::collision_energy:
        return "Collision Energy (if available)";
        break;
      case PeptideListColumn::charge:
        return "Peptide ion charge";
        break;
      case PeptideListColumn::experimental_mz:
        return "Observed m/z (experimental m/z of precursor)";
        break;
      case PeptideListColumn::sequence_nter:
        return "Flanking protein amino acid on peptide N-term side";
        break;
      case PeptideListColumn::sequence:
        return "Peptide sequence";
        break;
      case PeptideListColumn::chemical_formula:
        return "Peptide chemical formula";
        break;
      case PeptideListColumn::sequence_cter:
        return "Flanking protein amino acid on peptide C-term side";
        break;
      case PeptideListColumn::modifs:
        return "Peptide modifications";
        break;
      case PeptideListColumn::label:
        return "Peptide label";
        break;
      case PeptideListColumn::start:
        return "Peptide start position on protein";
        break;
      case PeptideListColumn::length:
        return "Peptide length";
        break;
      case PeptideListColumn::used:
        return "Number of subgroups in which this peptide is used";
        break;
      case PeptideListColumn::subgroups:
        return "List of subgroups in which this peptide is used";
        break;
      case PeptideListColumn::Evalue:
        return "Peptide Evalue";
        break;
      case PeptideListColumn::svmprob:
        return "Machine learning probability given by TIDD";
        break;
      case PeptideListColumn::qvalue:
        return "Peptide q-value";
        break;
      case PeptideListColumn::experimental_mhplus:
        return "Peptide ion observed mass [M+H]+";
        break;
      case PeptideListColumn::theoretical_mhplus:
        return "Peptide ion theoretical mass [M+H]+";
        break;
      case PeptideListColumn::delta_mhplus:
        return "Mass difference in Dalton between the peptide's observed and "
               "theoretical masses (observed - theoretical)";
        break;
      case PeptideListColumn::delta_ppm:
        return "Mass difference in ppm between the peptide's observed and "
               "theoretical masses (observed - theoretical)";
        break;
      case PeptideListColumn::tandem_hyperscore:
        return "X!Tandem HyperScore";
        break;
      case PeptideListColumn::mascot_score:
        return "Mascot ion score";
        break;
      case PeptideListColumn::mascot_expectation_value:
        return "Mascot expectation value";
        break;
      case PeptideListColumn::peptide_prophet_probability:
        return "Peptide prophet probability";
        break;
      case PeptideListColumn::peptide_inter_prophet_probability:
        return "Peptide inter prophet probability";
        break;
      case PeptideListColumn::omssa_evalue:
        return "OMSSA E-value";
        break;
      case PeptideListColumn::omssa_pvalue:
        return "OMSSA p-value";
        break;
      case PeptideListColumn::msgfplus_denovo:
        return "MS-GF de novo";
        break;
      case PeptideListColumn::msgfplus_energy:
        return "MS-GF energy";
        break;
      case PeptideListColumn::msgfplus_EValue:
        return "MS-GF E-value";
        break;
      case PeptideListColumn::msgfplus_raw:
        return "MS-GF raw score";
        break;
      case PeptideListColumn::msgfplus_SpecEValue:
        return "MS-GF spectral E-value";
        break;
      case PeptideListColumn::msgfplus_isotope_error:
        return "MS-GF isotope error";
        break;
      case PeptideListColumn::comet_xcorr:
        return "Comet result 'XCorr'";
        break;
      case PeptideListColumn::comet_deltacn:
        return "Comet result 'DeltaCn'";
        break;
      case PeptideListColumn::comet_deltacnstar:
        return "Comet result 'DeltaCnStar'";
        break;
      case PeptideListColumn::comet_spscore:
        return "Comet result 'SpScore'";
        break;
      case PeptideListColumn::comet_sprank:
        return "Comet result 'SpRank'";
        break;
      case PeptideListColumn::comet_expectation_value:
        return "Comet result 'Expectation value'";
        break;
      case PeptideListColumn::deepprot_original_count:
        return "DeepProt number of matched peaks before specfit";
        break;
      case PeptideListColumn::deepprot_fitted_count:
        return "DeepProt number of matched peaks after specfit";
        break;

      case PeptideListColumn::deepprot_match_type:
        return "DeepProt spectrum match type";
        break;
      case PeptideListColumn::deepprot_status:
        return "DeepProt peptide candidate status";
        break;
      case PeptideListColumn::deepprot_mass_delta:
        return "DeepProt PSM mass delta";
        break;
      case PeptideListColumn::deepprot_delta_positions:
        return "DeepProt PSM mass delta positions";
        break;
      case PeptideListColumn::sage_isotope_error:
        return "Sage Isotope error";
        break;
      case PeptideListColumn::sage_peptide_q:
        return "Sage peptide Q-value";
        break;
      case PeptideListColumn::sage_posterior_error:
        return "Sage peptide posterior error";
        break;
      case PeptideListColumn::sage_predicted_rt:
        return "Sage predicted rt";
        break;
      case PeptideListColumn::sage_sage_discriminant_score:
        return "Sage discriminant score";
        break;
      case PeptideListColumn::sage_spectrum_q:
        return "Sage spectrum Q-value";
        break;
      case PeptideListColumn::last:
        break;
    }
  return "";
}


int
PeptideTableModel::getColumnWidth(PeptideListColumn column)
{
  // qDebug() << "PeptideTableModel::getColumnWidth " << column;
  switch(column)
    {

      case PeptideListColumn::checked:
        break;

      case PeptideListColumn::peptide_grouping_id:
        return 120;
        break;
      case PeptideListColumn::sample:
        return 250;
        break;
      case PeptideListColumn::sequence:
        return 250;
        break;
      case PeptideListColumn::chemical_formula:
        return 160;
        break;
      case PeptideListColumn::sequence_cter:
        return 50;
        break;
      case PeptideListColumn::sequence_nter:
        return 50;
        break;
      case PeptideListColumn::charge:
        return 50;
        break;

      case PeptideListColumn::collision_energy:
        return 50;
        break;
      default:
        break;
    }
  return 100;
}


bool
PeptideTableModel::hasColumn(PeptideListColumn column)
{
  if((std::int8_t)column < m_nonIdentificationEngineColumnLimit)
    {
      return true;
    }
  qDebug() << _engine_columns_to_display.size();
  if(_engine_columns_to_display.find(column) !=
     _engine_columns_to_display.end())
    {
      return true;
    }
  return false;
}
