/**
 * \file pappsomspp/processing/specglob/sgposttreatment.h
 * \date 15/11/2023
 * \author Olivier Langella
 * \brief SpecGlobTool peptide model post treatment
 *
 * C++ implementation of the SpecGlob algorithm described in :
 * 1. Prunier, G. et al. Fast alignment of mass spectra in large proteomics
 * datasets, capturing dissimilarities arising from multiple complex
 * modifications of peptides. BMC Bioinformatics 24, 421 (2023).
 *
 *     HAL Id : hal-04296170 , version 1
 *     Mot de passe : hxo20cl
 *     DOI : 10.1186/s12859-023-05555-y
 */


/*
 * SpecGlobTool, Spectra to peptide alignment tool
 * Copyright (C) 2023  Olivier Langella
 * <olivier.langella@universite-paris-saclay.fr>
 *
 * This program is free software: you can redistribute ipetide to spectrum
 * alignmentt 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once


#include "peptidemodel.h"
#include "pappsomspp/export-import-config.h"


namespace pappso
{
namespace specglob
{
/**
 * @todo write docs
 */
class PMSPP_LIB_DECL PostTreatment
{
  public:
  /**
   * Default constructor
   */
  PostTreatment(pappso::PrecisionPtr precision,
                const PeptideModel &peptide_model);

  /**
   * Destructor
   */
  virtual ~PostTreatment();

  const PeptideModel &getBetterPeptideModel() const;
  const PeptideModel &getOriginalPeptideModel() const;

  bool findReplaceMutations();

  private:
  /** @brief whole processus to find a better peptide model
   *
   * assign residual mass to Cter
   * remove complementary mass delta
   * eliminate negative offsets (perhaps neutral loss)
   * check negative offsets for amino acid mass sums to remove
   * try better positions for mass delta
   *
   */
  void findBetterPeptideModel();

  /** @brief try to move offset (mass difference)
   *
   * for each mass difference position, try to move to other position if the
   * amino acid is not aligned, count matched peaks and compare to the previous
   * solution.
   * Keep only the better position
   */
  void tryBetterPositionOffsets();

  /** @brief try to remove offset (mass difference)
   *
   * for each mass difference position, count matched peaks and compare to the
   * previous solution. Removes mass difference if it does not degrade the
   * number of matched peaks
   */
  void tryToRemoveOffsets();

  /** @brief try to assign residual mass delta to non aligned elements
   *
   * This method is run only if there is not-aligned offSets. It may be
   * explained by an inadequate alignment at the start because we give some
   * advance to non-tryptic peptides. But, at the end of the alignment, we can
   * consider it was not the best choice Trying to improve this alignment by
   * adding not-aligned offSet with another one
   */
  void tryToCumulateOffSets();


  private:
  PeptideModel m_originalPeptideModel;
  PeptideModel m_betterPeptideModel;
  pappso::PrecisionPtr m_precision;
};
} // namespace specglob
} // namespace pappso
