
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ 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.
 *
 *     PAPPSOms++ 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 PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/
// ./tests/catch2-only-tests [peptidenaturalisotopeaverage] -s


#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp>

#include <iostream>
#include <pappsomspp/peptide/peptidenaturalisotopeaverage.h>
#include <pappsomspp/peptide/peptidenaturalisotopelist.h>
#include <pappsomspp/peptide/peptidestrparser.h>
// #include "common.h"
#include "config.h"

using namespace pappso;
using namespace std;
// using namespace pwiz::msdata;

// make test ARGS="-V -I 8,8"

TEST_CASE("Test peptidenaturalisotopeaverage", "[peptidenaturalisotopeaverage]")
{
  // Set the debugging message formatting pattern.
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));

  SECTION("..:: Test peptidenaturalisotopeaverage ::..",
          "[peptidenaturalisotopeaverage]")
  {

    std::cout << std::endl
              << "..:: Test natural isotope average ::.." << std::endl;

    Peptide peptide("ALLDEMAVVATEEYR");
    peptide.addAaModification(AaModification::getInstance("MOD:00397"), 0);

    pappso_double check_mass = 1747.84;
    MzRange test_mass(check_mass, PrecisionFactory::getDaltonInstance(0.01));
    REQUIRE(test_mass.contains(peptide.getMass() - MASSH2O));


    unsigned int askedIsotopeRank = 1;
    unsigned int isotopeLevel     = 2;
    unsigned int charge           = 1;
    PrecisionPtr precision        = PrecisionFactory::getPpmInstance(5);
    PeptideNaturalIsotopeAverage isotopeAverageMono(
      peptide.makePeptideSp(), askedIsotopeRank, 0, 1, precision);
    REQUIRE(MzRange(peptide.getMz(1), PrecisionFactory::getDaltonInstance(0.01))
              .contains(isotopeAverageMono.getMz()));


    PeptideNaturalIsotopeAverage isotopeAverage(peptide.makePeptideSp(),
                                                askedIsotopeRank,
                                                isotopeLevel,
                                                charge,
                                                precision);


    std::cout << "monosiotope mz=" << peptide.getMz(charge)
              << "average mz=" << isotopeAverage.getMz() << std::endl;
    std::cout << "intensity ratio =" << isotopeAverage.getIntensityRatio()
              << std::endl;

    std::cout << "z=" << isotopeAverage.getCharge() << std::endl;

    std::cout << "sum of :" << std::endl;
    unsigned int rank = 1;
    for(auto &&peptideNaturalIsotope : isotopeAverage.getComponents())
      {
        std::cout
          << "number=" << isotopeAverage.getIsotopeNumber() << " rank=" << rank
          << " mz=" << peptideNaturalIsotope.get()->getMz(charge)
          << " ratio=" << peptideNaturalIsotope.get()->getIntensityRatio(charge)
          << " formula="
          << peptideNaturalIsotope.get()->getFormula(charge).toStdString()
          << std::endl;
        rank++;
      }
    REQUIRE(isotopeAverage.getComponents().size() == 8);

    PrecisionPtr precision2 = PrecisionFactory::getDaltonInstance(0.2);
    PeptideNaturalIsotopeAverage isotopeAverage2(
      peptide.makePeptideSp(), 1, isotopeLevel, charge, precision2);

    std::cout << "monosiotope mz=" << peptide.getMz(charge)
              << "average mz=" << isotopeAverage2.getMz() << std::endl;
    std::cout << "intensity ratio =" << isotopeAverage2.getIntensityRatio()
              << std::endl;
    std::cout << "z=" << isotopeAverage2.getCharge() << std::endl;

    std::cout << "sum of :" << std::endl;
    rank = 1;
    for(auto &&peptideNaturalIsotope : isotopeAverage2.getComponents())
      {
        std::cout
          << "number=" << isotopeAverage2.getIsotopeNumber() << " rank=" << rank
          << " mz=" << peptideNaturalIsotope.get()->getMz(charge)
          << " ratio=" << peptideNaturalIsotope.get()->getIntensityRatio(charge)
          << " formula="
          << peptideNaturalIsotope.get()->getFormula(charge).toStdString()
          << std::endl;
        rank++;
      }
    REQUIRE(isotopeAverage2.getComponents().size() == 11);
    /*
    Spectrum spectrum_low_masses(spectrum_parent.applyCutOff(150));
    if (! spectrum_low_masses.equals(sremove_low_masses, precision)) {
       std::cerr << "spectrum_low_masses() != tandem"<< std::endl;
       return 1;
    }*/


    std::cout << std::endl
              << "..:: Test natural isotope average on labelled peptide ::.."
              << std::endl;

    peptide.addAaModification(AaModification::getInstance("MOD:00587"), 14);

    std::cout << std::endl
              << "labelled formula " << peptide.getFormula(1).toStdString()
              << std::endl;

    PeptideNaturalIsotopeAverage isotopeAverage_labeled(peptide.makePeptideSp(),
                                                        askedIsotopeRank,
                                                        isotopeLevel,
                                                        charge,
                                                        precision);


    std::cout << "labeled monosiotope mz=" << peptide.getMz(charge)
              << "average mz=" << isotopeAverage_labeled.getMz() << std::endl;
    std::cout << "intensity ratio ="
              << isotopeAverage_labeled.getIntensityRatio() << std::endl;
    std::cout << "z=" << isotopeAverage_labeled.getCharge() << std::endl;

    std::cout << "sum of :" << std::endl;
    rank = 1;
    for(auto &&peptideNaturalIsotope : isotopeAverage_labeled.getComponents())
      {
        std::cout
          << "labeled number=" << isotopeAverage_labeled.getIsotopeNumber()
          << " rank=" << rank
          << " mz=" << peptideNaturalIsotope.get()->getMz(charge)
          << " ratio=" << peptideNaturalIsotope.get()->getIntensityRatio(charge)
          << " formula="
          << peptideNaturalIsotope.get()->getFormula(charge).toStdString()
          << std::endl;
        rank++;
      }


    // peptideSp.get()->getSequence()= "AGYEVRDVHYSHYGR"  max_isotope_number= 3
    // spectrum.size= 307  parent_charge= 3
    ////ion_type_list.size= 9  max_isotope_rank= 2

    PeptideNaturalIsotopeList isotope_list(peptide.makePeptideSp());
    PeptideNaturalIsotopeAverage isotopeAverage_labeled2(
      isotope_list, askedIsotopeRank, isotopeLevel, charge, precision);

    REQUIRE(isotopeAverage_labeled.getMz() ==
            Catch::Approx(isotopeAverage_labeled2.getMz()));
  }
}
