/**
 * \file src/output/ods/mass_delta/validmassdeltasheet.cpp
 * \date 17/11/2020
 * \author Olivier Langella
 * \brief mass delta output
 */
/*******************************************************************************
 * Copyright (c) 2020 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 "validmassdeltasheet.h"
#include "../../../config.h"
#include <QDebug>
#include <pappsomspp/core/pappsoexception.h>
#include <cmath>


ValidMassDeltaSheet::ValidMassDeltaSheet(OdsExport *p_ods_export,
                                         CalcWriterInterface *p_writer,
                                         const Project *p_project)
  : _p_project(p_project)
{
  _p_ods_export = p_ods_export;
  _p_writer     = p_writer;
  p_writer->writeSheet("valid ppm mass delta stats");
  qDebug();
  ValidationState state = ValidationState::validAndChecked;
  std::vector<pappso::pappso_double> delta_list;
  pappso::Enums::PrecisionUnit unit = pappso::Enums::PrecisionUnit::ppm;

  for(IdentificationGroup *identification_group :
      _p_project->getIdentificationGroupList())
    {
      identification_group->collectMhDelta(delta_list, unit, state);
    }


  qDebug() << "accumulate";
  pappso::pappso_double sum =
    std::accumulate(delta_list.begin(), delta_list.end(), 0);

  qDebug() << "delta_list.size()=" << delta_list.size();
  pappso::pappso_double mean = 0;
  if(delta_list.size() > 0)
    {
      mean = sum / ((pappso::pappso_double)delta_list.size());
    }
  else
    {
      throw pappso::PappsoException(QObject::tr(
        "division by zero : no valid peptide found. Please check your "
        "filter parameters (decoy regexp or database particularly)"));
    }

  std::sort(delta_list.begin(), delta_list.end());
  pappso::pappso_double median = delta_list[(delta_list.size() / 2)];


  qDebug() << "ProjectWindow::computeMassPrecision sd";
  pappso::pappso_double sd = 0;
  for(pappso::pappso_double val : delta_list)
    {
      // sd = sd + ((val - mean) * (val - mean));
      sd += std::pow((val - mean), 2);
    }
  sd = sd / delta_list.size();
  sd = std::sqrt(sd);

  p_writer->writeCell("count");
  p_writer->writeCell(delta_list.size());
  p_writer->writeLine();
  p_writer->writeCell("mean");
  p_writer->writeCell(mean);
  p_writer->writeLine();
  p_writer->writeCell("median");
  p_writer->writeCell(median);
  p_writer->writeLine();


  p_writer->writeSheet("valid ppm mass delta list");

  p_writer->writeCell("ppm mass delta");
  p_writer->writeLine();

  for(auto &&delta_mass : delta_list)
    {
      p_writer->writeCell(delta_mass);
      p_writer->writeLine();
    }
  qDebug();
}
