
/*******************************************************************************
 * 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
 ******************************************************************************/


#include <iostream>
#include <pappsomspp/peptide/peptidenaturalisotopeaverage.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"


int
main()
{

  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));
  if(!test_mass.contains(peptide.getMass() - MASSH2O))
    {
      cerr << " peptide.getMass()-MASSH2O != check_mass " << peptide.getMass()
           << " " << check_mass << std::endl;
      return 1;
    }

  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);
  if(!MzRange(peptide.getMz(1), PrecisionFactory::getDaltonInstance(0.01))
        .contains(isotopeAverageMono.getMz()))
    {
      cerr << " MassRange(peptide.getMz(1), "
              "DaltonPrecision(0.01)).contains(isotopeAverageMono.getMz() "
           << (check_mass + MHPLUS) << " " << peptide.getMz(1) << " "
           << isotopeAverageMono.getMz() << std::endl;
      return 1;
    }


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


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

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

  cout << "sum of :" << std::endl;
  unsigned int rank = 1;
  for(auto &&peptideNaturalIsotope : isotopeAverage.getComponents())
    {
      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++;
    }
  if(isotopeAverage.getComponents().size() != 8)
    {
      cerr << "isotopeAverage.getComponents().size() "
           << isotopeAverage.getComponents().size() << " != 8 " << std::endl;
      return 1;
    }

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

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

  cout << "sum of :" << std::endl;
  rank = 1;
  for(auto &&peptideNaturalIsotope : isotopeAverage2.getComponents())
    {
      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++;
    }
  if(isotopeAverage2.getComponents().size() != 11)
    {
      cerr << " isotopeAverage2.getComponents().size() "
           << isotopeAverage2.getComponents().size() << " != 11" << std::endl;
      return 1;
    }
  /*
  Spectrum spectrum_low_masses(spectrum_parent.applyCutOff(150));
  if (! spectrum_low_masses.equals(sremove_low_masses, precision)) {
     cerr << "spectrum_low_masses() != tandem"<< std::endl;
     return 1;
  }*/


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

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

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

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


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

  cout << "sum of :" << std::endl;
  rank = 1;
  for(auto &&peptideNaturalIsotope : isotopeAverage_labeled.getComponents())
    {
      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++;
    }
  return 0;
}
