Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) SimplifyNewick

 

SimplifyNewick is a tool to randomly simplify Newicks.

 

SimplifyNewick is programmed in C++ using the IDE Qt Creator. It uses the Boost, CLN, Qt and STL libraries.

 

 

 

 

Downloads

 

 

 

 

 

 

Older downloads

 

Technical facts

 

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

 

 

 

 

 

Qt project file: ./ToolSimplifyNewick/ToolSimplifyNewickDesktop.pro

 

include(../../DesktopApplication.pri)
include(../../Libraries/BigInteger.pri)
include(../../Libraries/Boost.pri)
include(../../Libraries/GeneralConsole.pri)
include(../../Libraries/GeneralDesktop.pri)


include(../../Classes/CppFuzzy_equal_to/CppFuzzy_equal_to.pri)
include(../../Classes/CppNewick/CppNewick.pri)
include(../../Classes/CppNewickVector/CppNewickVector.pri)

include(ToolSimplifyNewickDesktop.pri)


SOURCES += \
    main.cpp

 

 

 

 

 

Qt project file: ./ToolSimplifyNewick/ToolSimplifyNewickWebsite.pro

 

include(../../Tools/Tool/ToolConsole.pri)

 

 

 

 

 

./ToolSimplifyNewick/ToolSimplifyNewickConsole.pri

 

INCLUDEPATH += \
    ../../Tools/ToolSimplifyNewick

SOURCES += \
    ../../Tools/ToolSimplifyNewick/toolsimplifynewickmaindialog.cpp \
    ../../Tools/ToolSimplifyNewick/toolsimplifynewickmenudialog.cpp

HEADERS += \
    ../../Tools/ToolSimplifyNewick/simplifynewickmaindialog.h \
    ../../Tools/ToolSimplifyNewick/simplifynewickmenudialog.h

OTHER_FILES += \
    ../../Tools/ToolSimplifyNewick/Licence.txt

RESOURCES += \
    ../../Tools/ToolSimplifyNewick/ToolSimplifyNewick.qrc

 

 

 

 

 

./ToolSimplifyNewick/ToolSimplifyNewickDesktop.pri

 

include(../../Tools/ToolSimplifyNewick/ToolSimplifyNewickConsole.pri)

FORMS += \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmaindialog.ui \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmenudialog.ui

SOURCES += \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmaindialog.cpp \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmenudialog.cpp

HEADERS += \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmaindialog.h \
    ../../Tools/ToolSimplifyNewick/qtsimplifynewickmenudialog.h

 

 

 

 

 

./ToolSimplifyNewick/ToolSimplifyNewickWebsite.pri

 

include(../../Tools/ToolSimplifyNewick/ToolSimplifyNewickConsole.pri)

SOURCES +=

HEADERS +=

 

 

 

 

 

./ToolSimplifyNewick/main.cpp

 

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <functional>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <QApplication>

#include "newickvector.h"
#include "simplifynewickmaindialog.h"
#include "qtsimplifynewickmenudialog.h"
#include "simplifynewickmaindialog.h"
#include "newick.h"
#pragma GCC diagnostic pop

void ShowProgramUse()
{
  std::cout
    << "Invalid use of SimplifyNewick\n"
    << "\n"
    << "Correct use:\n"
    << "\n"
    << "SimplifyNewick\n"
    << "SimplifyNewick [phylogeny]\n"
    << "SimplifyNewick [phylogeny] [maximum complexity]\n"
    << "\n"
    << "Example uses:"
    << "  SimplifyNewick\n"
    << "    -> start GUI mode\n"
    << "  SimplifyNewick '(((10,10),10),10)'\n"
    << "    -> simplify this phylogeny once\n"
    << "  SimplifyNewick '(((10,10),10),10)' 100\n"
    << "    -> simplify this phylogeny until complexity is lower than 100\n"
    << "\n"
    << std::endl;
}

int main(int argc, char* argv[])
{
  if (argc==1)
  {
    QApplication a(argc, argv);
    ribi::QtToolSimplifyNewickMenuDialog d;
    d.show();
    return a.exec();
  }
  if (argc > 3)
  {
    ShowProgramUse();
    return 0;
  }
  try
  {
    const ribi::NewickVector n(argv[1]);
  }
  catch (std::exception& e)
  {
    std::cerr << "Invalid Newick: " << e.what() << '\n';
    return 1;
  }
  if (argc == 3)
  {
    try
    {
      const BigInteger i(boost::lexical_cast<int>(argv[2]));
      if (i <= 0)
      {
        std::cerr << "The value of complexity must be a positive integer\n";
        return 1;
      }
    }
    catch(std::exception&)
    {
      std::cerr << "The value of complexity must be an integer\n";
      return 1;
    }
  }
  //All is well
  #ifdef NDEBUG
  std::srand(std::time(0)); //RandomizeTimer();
  #endif

  const std::string s_in(argv[1]);
  const BigInteger max_complexity =
    (argc == 3
    ? BigInteger(boost::lexical_cast<int>(argv[2]))
    : ribi::Newick::CalcComplexity(ribi::NewickVector(s_in).Peek()) - 1);
  const std::string s_out
    = ribi::ToolSimplifyNewickMainDialog::SimplifyNewick(s_in,max_complexity);
  std::cout << s_out << '\n';
  return 0;
}

 

 

 

 

 

./ToolSimplifyNewick/qtsimplifynewickmaindialog.h

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#ifndef QTTOOLSIMPLIFYNEWICKMAINDIALOG_H
#define QTTOOLSIMPLIFYNEWICKMAINDIALOG_H

#include <string>
#include <vector>

//#include <cln/cln.h>
#include "about.h"
#include "qthideandshowdialog.h"

namespace Ui {
  class QtToolSimplifyNewickMainDialog;
}

namespace ribi {

class QtToolSimplifyNewickMainDialog : public QtHideAndShowDialog
{
  Q_OBJECT

public:
  explicit QtToolSimplifyNewickMainDialog(QWidget *parent = 0) noexcept;
  QtToolSimplifyNewickMainDialog(const QtToolSimplifyNewickMainDialog&) = delete;
  QtToolSimplifyNewickMainDialog& operator=(const QtToolSimplifyNewickMainDialog&) = delete;
  ~QtToolSimplifyNewickMainDialog() noexcept;

private:
  Ui::QtToolSimplifyNewickMainDialog *ui;

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif

private slots:
  void OnAnyEditChange() noexcept;

  void on_button_start_clicked() noexcept;
  void on_edit_newick_textChanged(const QString &arg1) noexcept;
  void on_edit_max_complexity_textChanged(const QString &arg1) noexcept;
};

///CliToStr converts a cln::cl_I to std::string.
///From http://www.richelbilderbeek.nl/CppCliToStr.htm
//const std::string CliToStr(const cln::cl_I& i);

///IntToStrWithSep converts an integer to std::string
///and adds thousands seperators.
///From http://www.richelbilderbeek.nl/CppIntToStrWithSep.htm
//const std::string IntToStrWithSep(cln::cl_I i);

///GetMaxInt returns the highest possible value of a int.
///From http://www.richelbilderbeek.nl/CppGetMaxInt.htm
//int GetMaxInt();

///SafeIntToCli converts an int to cln::cl_I safely.
///From http://www.richelbilderbeek.nl/CppSafeIntToCli.htm
//const cln::cl_I SafeIntToCli(const int i);

///SimplifyNewick simplifies a Newick below a certain complexity.
///From http://www.richelbilderbeek.nl/CppSimplifyNewick.htm
//const std::string SimplifyNewick(
//  const std::string& newick, const cln::cl_I& max_complexity);

///SimplifyNewick simplifies a Newick below a certain complexity.
///From http://www.richelbilderbeek.nl/CppSimplifyNewick.htm
//const std::string SimplifyNewick(
//  const std::string& newick, const BigInteger& max_complexity);

} //~namespace ribi

#endif // QTTOOLSIMPLIFYNEWICKMAINDIALOG_H

 

 

 

 

 

./ToolSimplifyNewick/qtsimplifynewickmaindialog.cpp

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <string>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"

#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <QDesktopWidget>

#include "BigIntegerUtils.hh"

#include "newickvector.h"
#include "qtaboutdialog.h"
#include "simplifynewickmaindialog.h"
#include "qtsimplifynewickmaindialog.h"
#include "testtimer.h"
#include "newick.h"
#include "ui_qtsimplifynewickmaindialog.h"
#pragma GCC diagnostic pop

ribi::QtToolSimplifyNewickMainDialog::QtToolSimplifyNewickMainDialog(QWidget *parent) noexcept
  : QtHideAndShowDialog(parent),
    ui(new Ui::QtToolSimplifyNewickMainDialog)
{
  #ifndef NDEBUG
  Test();
  #endif
  ui->setupUi(this);

  //Put the dialog in the screen center
  const QRect screen = QApplication::desktop()->screenGeometry();
  this->move( screen.center() - this->rect().center() );

  #ifndef NDEBUG
  setWindowTitle(windowTitle()+" (debug)");
  #else
  setWindowTitle(windowTitle()+" (release)");
  #endif

  OnAnyEditChange();
}

ribi::QtToolSimplifyNewickMainDialog::~QtToolSimplifyNewickMainDialog() noexcept
{
  delete ui;
}

void ribi::QtToolSimplifyNewickMainDialog::OnAnyEditChange() noexcept
{
  ui->button_start->setEnabled(false);
  ui->text_output->clear();
  //Check newick
  try
  {
    const std::string s
      = ui->edit_newick->text().toStdString();
    Newick().CheckNewick(s);
    ui->text_output->appendPlainText(
      QString("Current Newick: ")
      + QString(s.c_str()));
  }
  catch (std::exception& e)
  {
    ui->text_output->appendPlainText(
      QString("Invalid Newick: ")
      + QString(e.what()));
    return;
  }
  //Display current complexity
  {
    const NewickVector n(
      ui->edit_newick->text().toStdString());
    const std::string s
      = ::bigIntegerToString(Newick().CalcComplexity(n.Peek()));
    ui->text_output->appendPlainText(
      QString("Current complexity: ")
      + QString(s.c_str()));
  }

  //Check complexity
  try
  {
    const std::string s
      = ui->edit_max_complexity->text().toStdString();

    const BigInteger i = stringToBigInteger(s);
    if (i < 0)
    {
      ui->text_output->appendPlainText(
        "Invalid input of maximum complexity: "
        "must be bigger than zero");
      return;
    }
  }
  catch (std::exception&)
  {
    //Too bad: BigInteger throws ordinary char pointers :-(
    ui->text_output->appendPlainText(
      "Invalid input of maximum complexity: "
      "must be a number");
    return;
  }
  catch (...)
  {
    ui->text_output->appendPlainText(
      "Invalid input of maximum complexity: "
      "must be a number");
    return;
  }
  //Set current maximum complexity to Newick complexity minus one
  {
    const NewickVector n(
      ui->edit_newick->text().toStdString());

    const BigInteger newick_complexity
      = Newick().CalcComplexity(n.Peek());
    const BigInteger current_complexity
      = ::stringToBigInteger(ui->edit_max_complexity->text().toStdString());
    if (current_complexity > newick_complexity)
    {

      ui->edit_max_complexity->setText(
        QString(::bigIntegerToString(newick_complexity - 1).c_str()));
    }
  }
  ui->button_start->setEnabled(true);
}

void ribi::QtToolSimplifyNewickMainDialog::on_button_start_clicked() noexcept
{
  ui->text_output->clear();
  //Obtain the onEditChange output
  OnAnyEditChange();

  #ifdef NDEBUG
  std::srand(std::time(0)); //RandomizeTimer();
  #endif

  const std::string s_in = ui->edit_newick->text().toStdString();
  const BigInteger max_complexity = ::stringToBigInteger(
    ui->edit_max_complexity->text().toStdString());

  const std::string s_out = ToolSimplifyNewickMainDialog::SimplifyNewick(s_in,max_complexity);
  NewickVector n(s_out);

  const std::string complexity
    = ::bigIntegerToString(Newick().CalcComplexity(n.Peek()));
  ui->text_output->appendHtml("Newick found:");
  ui->text_output->appendHtml(n.ToStr().c_str());
  ui->text_output->appendHtml("Newick complexity:");
  ui->text_output->appendHtml(boost::lexical_cast<std::string>(complexity).c_str());
}

void ribi::QtToolSimplifyNewickMainDialog::on_edit_newick_textChanged(const QString &) noexcept
{
  OnAnyEditChange();
}

void ribi::QtToolSimplifyNewickMainDialog::on_edit_max_complexity_textChanged(const QString &) noexcept
{
  OnAnyEditChange();
}

#ifndef NDEBUG
void ribi::QtToolSimplifyNewickMainDialog::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
}
#endif

 

 

 

 

 

./ToolSimplifyNewick/qtsimplifynewickmenudialog.h

 

#ifndef QTTOOLSIMPLIFYNEWICKMENUDIALOG_H
#define QTTOOLSIMPLIFYNEWICKMENUDIALOG_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include "qthideandshowdialog.h"
#pragma GCC diagnostic pop

namespace Ui {
  class QtToolSimplifyNewickMenuDialog;
}

namespace ribi {

class QtToolSimplifyNewickMenuDialog : public QtHideAndShowDialog
{
  Q_OBJECT

public:
  explicit QtToolSimplifyNewickMenuDialog(QWidget *parent = 0);
  QtToolSimplifyNewickMenuDialog(const QtToolSimplifyNewickMenuDialog&) = delete;
  QtToolSimplifyNewickMenuDialog& operator=(const QtToolSimplifyNewickMenuDialog&) = delete;
  ~QtToolSimplifyNewickMenuDialog() noexcept;

private:
  Ui::QtToolSimplifyNewickMenuDialog *ui;

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif

private slots:
  void on_button_about_clicked() noexcept;
  void on_button_quit_clicked() noexcept;
  void on_button_start_clicked() noexcept;
};

} //~namespace ribi

#endif // QTTOOLSIMPLIFYNEWICKMENUDIALOG_H

 

 

 

 

 

./ToolSimplifyNewick/qtsimplifynewickmenudialog.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include "qtsimplifynewickmenudialog.h"

#include "qtaboutdialog.h"
#include "qtsimplifynewickmaindialog.h"
#include "simplifynewickmaindialog.h"
#include "simplifynewickmenudialog.h"
#include "testtimer.h"
#include "trace.h"
#include "ui_qtsimplifynewickmenudialog.h"
#pragma GCC diagnostic pop

ribi::QtToolSimplifyNewickMenuDialog::QtToolSimplifyNewickMenuDialog(QWidget *parent)
  : QtHideAndShowDialog(parent),
    ui(new Ui::QtToolSimplifyNewickMenuDialog)
{
  #ifndef NDEBUG
  Test();
  #endif
  ui->setupUi(this);
}

ribi::QtToolSimplifyNewickMenuDialog::~QtToolSimplifyNewickMenuDialog() noexcept
{
  delete ui;
}

void ribi::QtToolSimplifyNewickMenuDialog::on_button_about_clicked() noexcept
{
  QtAboutDialog d(ToolSimplifyNewickMenuDialog().GetAbout());
  d.setWindowIcon(this->windowIcon());
  d.setStyleSheet(this->styleSheet());
  ShowChild(&d);
}

void ribi::QtToolSimplifyNewickMenuDialog::on_button_quit_clicked() noexcept
{
  close();
}

void ribi::QtToolSimplifyNewickMenuDialog::on_button_start_clicked() noexcept
{
  QtToolSimplifyNewickMainDialog d;
  ShowChild(&d);
}

#ifndef NDEBUG
void ribi::QtToolSimplifyNewickMenuDialog::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  QtToolSimplifyNewickMainDialog();
  const TestTimer test_timer(__func__,__FILE__,1.0);
}
#endif

 

 

 

 

 

./ToolSimplifyNewick/simplifynewickmaindialog.h

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#ifndef TOOLSIMPLIFYNEWICKMAINDIALOG_H
#define TOOLSIMPLIFYNEWICKMAINDIALOG_H

#include <string>
#include <vector>

struct BigInteger;

namespace ribi {

struct ToolSimplifyNewickMainDialog
{
  ///SimplifyNewick simplifies a Newick below a certain complexity,
  ///in a frequency dependent way.
  ///For example, for the phylogeny (100,2), SimplifyNewick
  ///returns (99,2) 50x as often as (100,1).
  ///From http://www.richelbilderbeek.nl/CppSimplifyNewick.htm
  static std::string SimplifyNewick(
    const std::string& s,
    const BigInteger& max_complexity);

  private:
  static int SumSecond(const std::vector<std::pair<std::vector<int>,int> >& v) noexcept;

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif
};

} //~namespace ribi

#endif // TOOLSIMPLIFYNEWICKMAINDIALOG_H

 

 

 

 

 

./ToolSimplifyNewick/simplifynewickmenudialog.h

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#ifndef TOOLSIMPLIFYNEWICKMENUDIALOG_H
#define TOOLSIMPLIFYNEWICKMENUDIALOG_H

#include "menudialog.h"

namespace ribi {

///GUI independent ToolSimplifyNewick menu dialog
struct ToolSimplifyNewickMenuDialog final : public MenuDialog
{
  About GetAbout() const noexcept override;
  Help GetHelp() const noexcept override;
  boost::shared_ptr<const Program> GetProgram() const noexcept override;
  std::string GetVersion() const noexcept override;
  std::vector<std::string> GetVersionHistory() const noexcept override;

  private:
  int ExecuteSpecific(const std::vector<std::string>& argv) noexcept override;

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif
};

} //~namespace ribi

#endif // TOOLSIMPLIFYNEWICKMENUDIALOG_H

 

 

 

 

 

./ToolSimplifyNewick/toolsimplifynewickmaindialog.cpp

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#include "simplifynewickmaindialog.h"

#include <iostream>

#include "newick.h"
#include "newickvector.h"

/*

std::vector<std::string> ribi::ToolSimplifyNewickMainDialog::GetBadlyFormedNewicks()
{
  std::vector<std::string> v;
  v.push_back("1,(2,3))");
  v.push_back("(1,(2,3)");
  v.push_back("(1,((2,3))");
  v.push_back("(1,(2,3)))");

  v.push_back("(((1,(2,3)),4)");
  v.push_back("((2,((1,3)),4)");
  v.push_back("((2,(3,1))),4)");
  v.push_back("((2,(3,4)),1))");

  return v;
}

std::vector<std::string> ribi::ToolSimplifyNewickMainDialog::GetWellFormedNewicks()
{
  std::vector<std::string> v;
  v.push_back("(1,(2,3))");
  v.push_back("(2,(1,3))");
  v.push_back("(2,(3,1))");
  v.push_back("(1,(1,1))");

  v.push_back("((1,(2,3)),4)");
  v.push_back("((2,(1,3)),4)");
  v.push_back("((2,(3,1)),4)");
  v.push_back("((2,(3,4)),1)");
  v.push_back("((1,(1,1)),1)");

  v.push_back("(1,((20,(30,40)),50))");
  v.push_back("(10,((1,(30,40)),50))");
  v.push_back("(10,((20,(1,40)),50))");
  v.push_back("(10,((20,(30,1)),50))");
  v.push_back("(10,((20,(30,40)),1))");
  v.push_back("(1,((1,(1,1)),1))");

  v.push_back("(((1,(20,30)),40),50)");
  v.push_back("(((10,(1,30)),40),50)");
  v.push_back("(((10,(20,1)),40),50)");
  v.push_back("(((10,(20,30)),1),50)");
  v.push_back("(((10,(20,30)),40),1)");
  v.push_back("(((11,(1,1)),1),1)");

  v.push_back("(1,(((200,(300,400)),500),600))");
  v.push_back("(100,(((1,(300,400)),500),600))");
  v.push_back("(100,(((200,(1,400)),500),600))");
  v.push_back("(100,(((200,(300,1)),500),600))");
  v.push_back("(100,(((200,(300,400)),1),600))");
  v.push_back("(100,(((200,(300,400)),500),1))");
  v.push_back("(1,(((1,(1,1)),1),1))");

  v.push_back("((((1,(200,300)),400),500),600)");
  v.push_back("((((100,(1,300)),400),500),600)");
  v.push_back("((((100,(200,1)),400),500),600)");
  v.push_back("((((100,(200,300)),1),500),600)");
  v.push_back("((((100,(200,300)),400),1),600)");
  v.push_back("((((100,(200,300)),400),500),1)");
  v.push_back("((((1,(1,1)),1),1),1)");

  v.push_back("(1,(1,1),(1,1))");
  return v;
}

void ribi::ToolSimplifyNewickMainDialog::TestNewickMustFail(const std::string& s)
{
  try
  {
    const NewickVector n(s);
  }
  catch(std::invalid_argument& e)
  {
    //No problem
    return;
  }
  std::stringstream err_msg;
  err_msg << "Test that had to fail succeeded from newick '" << s << '\'';
  throw std::logic_error(err_msg.str());
}

void ribi::ToolSimplifyNewickMainDialog::TestNewick(const std::string& s)
{
  const NewickVector n(s);
  std::cout  << "Obtaining simpler newicks of " << s;

  const std::vector<NewickVector> v = n.GetSimplerNewicks();

  if (v.empty()) std::cout << "[no simpler newick obtained]\n";
  typedef std::vector<NewickVector>::const_iterator Iterator;
  const Iterator j = v.end();
  for (Iterator i=v.begin(); i!=j; ++i)
  {
    std::cout << (*i).ToStr();
  }

  std::cout << std::endl;
}

void ribi::ToolSimplifyNewickMainDialog::TestNewicksFromFile()
{
  if (!FileExists("subs_in.txt")) throw std::runtime_error("File subs_in.txt must exist");
  const std::vector<std::string> newicks = FileToVector("subs_in.txt");

  //std::vector<std::string>::const_iterator newick_str = newicks.begin();
  //const std::vector<std::string>::const_iterator last_newick_str = newicks.end();

  std::ofstream f("subs_out.txt");

  for(const std::string& s: newicks)
  {
    if (s.empty()) continue;
    f << s;
    NewickVector n(s);

    const std::vector<NewickVector> simplers = n.GetSimplerNewicks();
    for(const NewickVector& simple: simplers)
    {
      f << '\t' << simple.ToStr();
    }
    f << '\n';

  }
}

void ribi::ToolSimplifyNewickMainDialog::TestPredefinedNewicks()
{
  const std::vector<std::string> newicks = GetWellFormedNewicks();
  std::vector<std::string>::const_iterator newick_str = newicks.begin();
  const std::vector<std::string>::const_iterator last_newick_str = newicks.end();

  for ( ; newick_str!=last_newick_str; ++newick_str)
  {
    TestNewick(*newick_str);
  }
}

void ribi::ToolSimplifyNewickMainDialog::TestNewicksManually()
{
  while(1)
  {
    std::cout << "Please enter a Newick, for example '(1,(2,3))'. Press enter to quit.\n";
    const std::string s = AskUserForString();
    if (s.empty()) return;
    try
    {
      TestNewick(s);
    }
    catch (std::invalid_argument& e)
    {
      std::cout << "Invalid input: " << e.what() << '\n' << std::endl;
    }
  }
}
*/
std::string ribi::ToolSimplifyNewickMainDialog::SimplifyNewick(
  const std::string& s,
  const BigInteger& max_complexity)
{
  std::unique_ptr<const NewickVector> n{ new NewickVector(s) };
  while (1)
  {
    const BigInteger complexity = Newick().CalcComplexity(n->Peek());
    if (complexity <= max_complexity) return n->ToStr();
    const std::vector<std::pair<std::vector<int>,int> > v
      = Newick().GetSimplerNewicksFrequencyPairs(n->Peek());
    if (v.empty()) return n->ToStr();
    const int sum = SumSecond(v);

    const int index_chosen = std::rand() % sum;
    //std::clog << "Index chosen: " << index_chosen << '\n';
    int current_sum = 0;
    for (int i=0; ;++i)
    {
      assert(i != boost::numeric_cast<int>(v.size()));
      current_sum+=v[i].second;
      //std::clog << "Index " << i << ", sum: " << current_sum << '\n';
      if (current_sum >= index_chosen)
      {
        //std::clog << "Index " << i << " chosen\n";
        n.reset(new NewickVector(v[i].first));
        break;
      }
    }
  }
}

///SimplifyNewickFreqInd simplifies a Newick below a certain
///complexity, independent of the frequencies in the
///phylogeny.
///For example, for the phylogeny (100,2), SimplifyNewickFreqInd
///returns (99,2) as often as (100,1).
///From http://www.richelbilderbeek.nl/CppSimplifyNewickFreqInd.htm
/*
const std::string SimplifyNewickFreqInd(
  const std::string& s, const cln::cl_I& max_complexity)
{
  BinaryNewickVector n(s);
  while (1)
  {
    const cln::cl_I complexity = CalcComplexity(n.Get());
    if (complexity <= max_complexity) return n.ToStr();
    const std::vector<NewickVector> v = n.GetSimplerNewicks();
    if (v.empty()) return n.ToStr();
    const int i = std::rand() % boost::numeric_cast<int>(v.size());
    n = v[i];
  }
}
*/

int ribi::ToolSimplifyNewickMainDialog::SumSecond(
  const std::vector<std::pair<std::vector<int>,int> >& v) noexcept
{
  int sum = 0;
  typedef std::pair<std::vector<int>,int> Pair;
  for(const Pair& p: v)
  {
    sum+=p.second;
  }
  return sum;
}

 

 

 

 

 

./ToolSimplifyNewick/toolsimplifynewickmenudialog.cpp

 

//---------------------------------------------------------------------------
/*
SimplifyNewick, tool to randomly simplify Newick phylogenies
Copyright (C) 2010-2015 Richel Bilderbeek

This program 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.

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/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm
//---------------------------------------------------------------------------
#include "simplifynewickmenudialog.h"

#include <cassert>
#include <iostream>

#include "newickvector.h"
#include "richelbilderbeekprogram.h"
#include "testtimer.h"

int ribi::ToolSimplifyNewickMenuDialog::ExecuteSpecific(const std::vector<std::string>& argv) noexcept
{
  #ifndef NDEBUG
  Test();
  #endif
  const int argc = static_cast<int>(argv.size());
  if (argc == 1)
  {
    std::cout << GetHelp() << '\n';
    return 1;
  }
  assert(!"TODO");
  return 1;
}

ribi::About ribi::ToolSimplifyNewickMenuDialog::GetAbout() const noexcept
{
  About a(
    "Richel Bilderbeek",
    "SimplifyNewick",
    "tool to randomly simplify Newick phylogenies",
    "the 19th of September 2013",
    "2010-2015",
    "http://www.richelbilderbeek.nl/ToolSimplifyNewick.htm",
    GetVersion(),
    GetVersionHistory());
  a.AddLibrary("NewickVector version: " + NewickVector::GetVersion());
  return a;
}

ribi::Help ribi::ToolSimplifyNewickMenuDialog::GetHelp() const noexcept
{
  return Help(
    this->GetAbout().GetFileTitle(),
    this->GetAbout().GetFileDescription(),
    {

    },
    {

    }
  );
}

boost::shared_ptr<const ribi::Program> ribi::ToolSimplifyNewickMenuDialog::GetProgram() const noexcept
{
  const boost::shared_ptr<const Program> p {
    new ProgramSimplifyNewick
  };
  assert(p);
  return p;
}

std::string ribi::ToolSimplifyNewickMenuDialog::GetVersion() const noexcept
{
  return "3.1";
}

std::vector<std::string> ribi::ToolSimplifyNewickMenuDialog::GetVersionHistory() const noexcept
{
  return {
    "2010-09-12: version 1.0: initial version",
    "2010-09-16: version 1.1: use of BinaryNewickVector version 1.0, added library version numbers in About screen, added 'What's New?' dialog, added difference in debug and release version",
    "2010-09-16: version 1.2: simplification is frequency dependent. For example: (100,2) will be simplified to (99,2) 50x more often than to (100,1)",
    "2011-05-07: version 2.0: use NewickVector instead of BinaryNewickVector, replace custom about and whats new dialog by QtAboutDialog",
    "2013-09-19: version 3.0: conformized for ProjectRichelBilderbeek",
    "2013-11-05: version 3.1: conformized for ProjectRichelBilderbeekConsole"
  };
}

#ifndef NDEBUG
void ribi::ToolSimplifyNewickMenuDialog::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
}
#endif

 

 

 

 

 

./ToolSimplifyNewick/zip.sh

 

#!/bin/sh
#zip packs all the files to port into a single .zip file,
#minicking the same folder structure
#Folder structure
# *
#   * Classes
#     * CppAbout
#     * CppNewick
#     * CppNewickVector
#     * CppQtAboutDialog
#     * CppTrace
#   * Libraries
#     * bigint-2010.04.30
#   * Tools
#    * ToolSimplifyNewick
echo "Mimicking file structure"
mkdir temp_zip
mkdir temp_zip/Classes
mkdir temp_zip/Classes/CppAbout
mkdir temp_zip/Classes/CppNewick
mkdir temp_zip/Classes/CppNewickVector
mkdir temp_zip/Classes/CppQtAboutDialog
mkdir temp_zip/Classes/CppTrace
mkdir temp_zip/Libraries
mkdir temp_zip/Libraries/bigint-2010.04.30
mkdir temp_zip/Tools
mkdir temp_zip/Tools/ToolSimplifyNewick

echo "Copying files"
cp ../../Classes/CppAbout/*.* temp_zip/Classes/CppAbout
cp ../../Classes/CppNewick/*.* temp_zip/Classes/CppNewick
cp ../../Classes/CppNewickVector/*.* temp_zip/Classes/CppNewickVector
cp ../../Classes/CppQtAboutDialog/*.* temp_zip/Classes/CppQtAboutDialog
cp ../../Classes/CppTrace/*.* temp_zip/Classes/CppTrace
cp ../../Libraries/bigint-2010.04.30/*.* temp_zip/Libraries/bigint-2010.04.30
cp ../../Tools/ToolSimplifyNewick/*.* temp_zip/Tools/ToolSimplifyNewick

echo "Compressing files"
cd temp_zip

zip -r ToolSimplifyNewickSource_2_0 Classes
zip -r ToolSimplifyNewickSource_2_0 Libraries
zip -r ToolSimplifyNewickSource_2_0 Tools
cd ..
cp temp_zip/ToolSimplifyNewickSource_2_0.zip ToolSimplifyNewickSource_2_0.zip

echo "Cleaning up"
#Classes
rm temp_zip/Classes/CppAbout/*.*
rm temp_zip/Classes/CppNewick/*.*
rm temp_zip/Classes/CppNewickVector/*.*
rm temp_zip/Classes/CppQtAboutDialog/*.*
rm temp_zip/Classes/CppTrace/*.*
rmdir temp_zip/Classes/CppAbout
rmdir temp_zip/Classes/CppNewick
rmdir temp_zip/Classes/CppNewickVector
rmdir temp_zip/Classes/CppQtAboutDialog
rmdir temp_zip/Classes/CppTrace
rmdir temp_zip/Classes
#Libraries
rm temp_zip/Libraries/bigint-2010.04.30/*.*
rmdir temp_zip/Libraries/bigint-2010.04.30
rmdir temp_zip/Libraries
#Tools
rm temp_zip/Tools/ToolSimplifyNewick/*.*
rmdir temp_zip/Tools/ToolSimplifyNewick
rmdir temp_zip/Tools
rm temp_zip/*.*
rmdir temp_zip
echo "Done"

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml