text:
/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2020 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <es-log/trace-log.h>
#include <boost/algorithm/string.hpp>
#include <Core/Utils/Legacy/MemoryUtil.h>
#include <Interface/Application/GuiLogger.h>
#include <Interface/Application/SCIRunMainWindow.h>
#include <Interface/Application/NetworkEditor.h>
#include <Interface/Application/ProvenanceWindow.h>
#include <Interface/Application/PreferencesWindow.h>
#include <Interface/Application/TagManagerWindow.h>
#include <Interface/Application/TreeViewCollaborators.h>
#include <Interface/Application/MainWindowCollaborators.h>
#include <Interface/Application/GuiCommands.h>
#include <Interface/Application/NetworkEditorControllerGuiProxy.h>
#include <Interface/Application/NetworkExecutionProgressBar.h>
#include <Interface/Application/DialogErrorControl.h>
#include <Interface/Application/TriggeredEventsWindow.h>
#include <Interface/Modules/Base/ModuleDialogGeneric.h> //TODO
#include <Dataflow/Engine/Controller/ProvenanceManager.h>
#include <Dataflow/Serialization/Network/XMLSerializer.h>
#include <Core/Application/Application.h>
#include <Core/Application/Preferences/Preferences.h>
#include <Core/Logging/Log.h>
#include <Dataflow/Serialization/Network/NetworkDescriptionSerialization.h>
#include <Dataflow/Serialization/Network/Importer/NetworkIO.h>

#ifdef BUILD_WITH_PYTHON
#include <Interface/Application/PythonConsoleWidget.h>
#include <Core/Python/PythonInterpreter.h>
#endif

using namespace SCIRun;
using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Engine;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Dataflow::State;
using namespace SCIRun::Core::Commands;
using namespace SCIRun::Core::Logging;
using namespace SCIRun::Core;
using namespace SCIRun::Core::Algorithms;

SCIRunMainWindow::SCIRunMainWindow()
{
  setupUi(this);
  builder_ = makeShared<NetworkEditorBuilder>(this);
  dockManager_ = new DockManager(dockSpace_, this);

  {
    SharedPointer<TextEditAppender> logger(new TextEditAppender(logTextBrowser_));
    GuiLog::Instance().addCustomSink(logger);
  }

  startup_ = true;

  QCoreApplication::setOrganizationName("SCI:CIBC Software");
  QCoreApplication::setApplicationName("SCIRun5");

  setAttribute(Qt::WA_DeleteOnClose);

  menubar_->setStyleSheet("QMenuBar::item::selected{background-color : rgb(66, 66, 69); } QMenuBar::item::!selected{ background-color : rgb(66, 66, 69); } ");

  dialogErrorControl_.reset(new DialogErrorControl(this));
  setupTagManagerWindow();

  setupPreferencesWindow();

  setupNetworkEditor();

  setTipsAndWhatsThis();

  connect(actionExecuteAll_, SIGNAL(triggered()), this, SLOT(executeAll()));
  connect(actionNew_, SIGNAL(triggered()), this, SLOT(newNetwork()));

  setActionIcons();

  createStandardToolbars();
  createExecuteToolbar();
  createAdvancedToolbar();
  createMacroToolbar();

  #ifdef __APPLE__
  connect(actionLaunchNewInstance_, SIGNAL(triggered()), this, SLOT(launchNewInstance()));
  #else
  menuFile_->removeAction(actionLaunchNewInstance_);
  #endif

  {
    auto searchAction = new QWidgetAction(this);
    searchAction->setDefaultWidget(new NetworkSearchWidget(networkEditor_));
    addToolBarBreak();
    auto searchBar = addToolBar("&Search");
    searchBar->setObjectName("SearchToolBar");
    WidgetStyleMixin::toolbarStyle(searchBar);
    searchBar->addAction(searchAction);
    connect(actionSearchBar_, SIGNAL(toggled(bool)), searchBar, SLOT(setVisible(bool)));
    connect(searchBar, SIGNAL(visibilityChanged(bool)), actionSearchBar_, SLOT(setChecked(bool)));
    searchBar->setVisible(false);
  }

  setContextMenuPolicy(Qt::NoContextMenu);

  scrollArea_->viewport()->setBackgroundRole(QPalette::Dark);
  scrollArea_->viewport()->setAutoFillBackground(true);
  scrollArea_->setStyleSheet(styleSheet());

  connect(actionSave_As_, SIGNAL(triggered()), this, SLOT(saveNetworkAs()));
  connect(actionSave_, SIGNAL(triggered()), this, SLOT(saveNetwork()));
  connect(actionLoad_, SIGNAL(triggered()), this, SLOT(loadNetwork()));
  connect(actionImportNetwork_, SIGNAL(triggered()), this, SLOT(importLegacyNetwork()));
  connect(actionQuit_, SIGNAL(triggered()), this, SLOT(close()));
  connect(actionRunScript_, SIGNAL(triggered()), this, SLOT(runScript()));

  connect(actionRunMacro1_, SIGNAL(triggered()), this, SLOT(runMacro()));
  connect(actionRunMacro2_, SIGNAL(triggered()), this, SLOT(runMacro()));
  connect(actionRunMacro3_, SIGNAL(triggered()), this, SLOT(runMacro()));
  connect(actionRunMacro4_, SIGNAL(triggered()), this, SLOT(runMacro()));
  connect(actionRunMacro5_, SIGNAL(triggered()), this, SLOT(runMacro()));

  {
    QFile importerXML(":/general/Resources/LegacyModuleImporter.xml");

    if (importerXML.open(QIODevice::ReadOnly | QIODevice::Text))
    {
      std::ostringstream ostr;
      QTextStream in(&importerXML);
      while (!in.atEnd())
      {
        QString line = in.readLine();
        ostr << line.toStdString();
      }
      std::istringstream file(ostr.str());
      LegacyNetworkIO::initializeStateConverter(file);
    }
  }

  actionQuit_->setShortcut(QKeySequence::Quit);

#ifdef __APPLE__
  actionToggleFullScreenMode_->setShortcut(QApplication::translate("SCIRunMainWindow", "Meta+Ctrl+F", 0));
#else
  actionToggleFullScreenMode_->setShortcut(Qt::Key_F11);
#endif

  actionDelete_->setShortcuts(QList<QKeySequence>() << QKeySequence::Delete << Qt::Key_Backspace);

	connect(actionRunNewModuleWizard_, SIGNAL(triggered()), this, SLOT(runNewModuleWizard()));
	actionRunNewModuleWizard_->setDisabled(true);

  connect(actionAbout_, SIGNAL(triggered()), this, SLOT(displayAcknowledgement()));
  connect(actionCreateToolkitFromDirectory_, SIGNAL(triggered()), this, SLOT(helpWithToolkitCreation()));

  connect(helpActionPythonAPI_, SIGNAL(triggered()), this, SLOT(loadPythonAPIDoc()));
  connect(helpActionModuleFuzzySearch_, SIGNAL(triggered()), this, SLOT(showModuleFuzzySearchHelp()));
  connect(helpActionSnippets_, SIGNAL(triggered()), this, SLOT(showSnippetHelp()));
  connect(helpActionClipboard_, SIGNAL(triggered()), this, SLOT(showClipboardHelp()));
	connect(helpActionTagLayer_, SIGNAL(triggered()), this, SLOT(showTagHelp()));
	connect(helpActionTriggeredScripts_, SIGNAL(triggered()), this, SLOT(showTriggerHelp()));
  connect(helpActionNewUserWizard_, SIGNAL(triggered()), this, SLOT(launchNewUserWizard()));
  connect(helpActionPythonWizard_, SIGNAL(triggered()), this, SLOT(launchPythonWizard()));

  connect(actionReset_Window_Layout, SIGNAL(triggered()), this, SLOT(resetWindowLayout()));
  connect(actionToggleFullScreenMode_, SIGNAL(triggered()), this, SLOT(toggleFullScreen()));

#ifndef BUILD_WITH_PYTHON
  actionRunScript_->setEnabled(false);
#endif

  for (int i = 0; i < MaxRecentFiles; ++i)
  {
    recentFileActions_.push_back(new QAction(this));
    recentFileActions_[i]->setVisible(false);
    recentNetworksMenu_->addAction(recentFileActions_[i]);
    connect(recentFileActions_[i], SIGNAL(triggered()), this, SLOT(loadRecentNetwork()));
  }

	setupScriptedEventsWindow();
  setupProvenanceWindow();

  setupDevConsole();
  setupPythonConsole();

  connect(prefsWindow_->defaultNotePositionComboBox_, SIGNAL(activated(int)), this, SLOT(readDefaultNotePosition(int)));
  connect(prefsWindow_->defaultNoteSizeComboBox_, SIGNAL(activated(int)), this, SLOT(readDefaultNoteSize(int)));
  connect(prefsWindow_->cubicPipesRadioButton_, SIGNAL(clicked()), this, SLOT(makePipesCubicBezier()));
  connect(prefsWindow_->manhattanPipesRadioButton_, SIGNAL(clicked()), this, SLOT(makePipesManhattan()));
  connect(prefsWindow_->euclideanPipesRadioButton_, SIGNAL(clicked()), this, SLOT(makePipesEuclidean()));
  connect(prefsWindow_->maxCoresSpinBox_, SIGNAL(valueChanged(int)), this, SLOT(maxCoreValueChanged(int)));
  //TODO: will be a user or network setting
  makePipesEuclidean();

  connect(moduleFilterLineEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(filterModuleNamesInTreeView(const QString&)));

  connect(prefsWindow_->modulesSnapToCheckBox_, SIGNAL(stateChanged(int)), this, SLOT(modulesSnapToChanged()));
  connect(prefsWindow_->modulesSnapToCheckBox_, SIGNAL(stateChanged(int)), networkEditor_, SIGNAL(snapToModules()));
  connect(prefsWindow_->portSizeEffectsCheckBox_, SIGNAL(stateChanged(int)), this, SLOT(highlightPortsChanged()));
  connect(prefsWindow_->portSizeEffectsCheckBox_, SIGNAL(stateChanged(int)), networkEditor_, SIGNAL(highlightPorts(int)));
  connect(prefsWindow_->dockableModulesCheckBox_, SIGNAL(stateChanged(int)), this, SLOT(adjustModuleDock(int)));

  makeFilterButtonMenu();

  connect(prefsWindow_->scirunDataPushButton_, SIGNAL(clicked()), this, SLOT(setDataDirectoryFromGUI()));
  connect(prefsWindow_->screenshotPathPushButton_, SIGNAL(clicked()), this, SLOT(setScreenshotDirectoryFromGUI()));
  //connect(prefsWindow_->addToPathButton_, SIGNAL(clicked()), this, SLOT(addToPathFromGUI()));
  connect(actionFilter_modules_, SIGNAL(triggered()), this, SLOT(setFocusOnFilterLine()));
  connect(actionAddModule_, SIGNAL(triggered()), this, SLOT(addModuleKeyboardAction()));
  actionAddModule_->setVisible(false);
  connect(actionSelectModule_, SIGNAL(triggered()), this, SLOT(selectModuleKeyboardAction()));
  actionSelectModule_->setVisible(false);
  connect(actionReportIssue_, SIGNAL(triggered()), this, SLOT(reportIssue()));
  connect(actionSelectMode_, SIGNAL(toggled(bool)), this, SLOT(setSelectMode(bool)));
  connect(actionDragMode_, SIGNAL(toggled(bool)), this, SLOT(setDragMode(bool)));
	connect(actionToggleTagLayer_, SIGNAL(toggled(bool)), this, SLOT(toggleTagLayer(bool)));
  connect(actionToggleMetadataLayer_, SIGNAL(toggled(bool)), this, SLOT(toggleMetadataLayer(bool)));
  connect(actionResetNetworkZoom_, SIGNAL(triggered()), this, SLOT(zoomNetwork()));
  connect(actionZoomIn_, SIGNAL(triggered()), this, SLOT(zoomNetwork()));
  connect(actionZoomOut_, SIGNAL(triggered()), this, SLOT(zoomNetwork()));
  connect(actionZoomBestFit_, SIGNAL(triggered()), this, SLOT(zoomNetwork()));
  connect(actionStateViewer_, &QAction::triggered, [this]() { networkEditor_->showStateViewer(); });

  auto dimFunc = [this](const char* type)
  {
    return [this, type]()
    {
      showStatusMessage(QString("Dimming connections of type ") + type, NetworkEditor::ConnectionHideTimeMS_);
      networkEditor_->hidePipesByType(type);
    };
  };
  connect(actionHideFieldPipes_, &QAction::triggered, dimFunc("Field"));
  connect(actionHideMatrixPipes_, &QAction::triggered, dimFunc("Matrix"));
  connect(actionHideStringPipes_, &QAction::triggered, dimFunc("String"));
  connect(actionHideGeometryPipes_, &QAction::triggered, dimFunc("Geometry"));
  connect(actionHideColorMapPipes_, &QAction::triggered, dimFunc("ColorMap"));

  actionCut_->setIcon(QPixmap(":/general/Resources/cut.png"));
  actionCopy_->setIcon(QPixmap(":/general/Resources/copy.png"));
  actionPaste_->setIcon(QPixmap(":/general/Resources/paste.png"));

  connect(actionKeyboardShortcuts_, SIGNAL(triggered()), this, SLOT(showKeyboardShortcutsDialog()));

  //TODO: store in xml file, add to app resources
  {
    ToolkitInfo fwdInv{ "http://www.sci.utah.edu/images/software/forward-inverse/forward-inverse-mod.png",
#ifdef __APPLE__
      "https://codeload.github.com/SCIInstitute/FwdInvToolkit/zip/v1.4.3",
#else
      "http://sci.utah.edu/devbuilds/scirun5/toolkits/FwdInvToolkit_v1.4.3.zip",
#endif
      "FwdInvToolkit_stable.zip" };
    fwdInv.setupAction(actionForwardInverseStable_, this);
  }
  {
    ToolkitInfo fwdInvNightly{ "http://www.sci.utah.edu/images/software/forward-inverse/forward-inverse-mod.png",
      "https://codeload.github.com/SCIInstitute/FwdInvToolkit/zip/master",
      "FwdInvToolkit_nightly.zip" };
    fwdInvNightly.setupAction(actionForwardInverseNightly_, this);
  }
  {
    ToolkitInfo brainStim{ "http://www.sci.utah.edu/images/software/BrainStimulator/brain-stimulator-mod.png",
    #ifdef __APPLE__
      "https://codeload.github.com/SCIInstitute/BrainStimulator/zip/BrainStimulator_v1.3",
    #else
      "http://sci.utah.edu/devbuilds/scirun5/toolkits/BrainStimulator_v1.3.zip",
    #endif
      "BrainStimulator_stable.zip" };
    brainStim.setupAction(actionBrainStimulatorStable_, this);
  }
  {
    ToolkitInfo brainStimNightly{ "http://www.sci.utah.edu/images/software/BrainStimulator/brain-stimulator-mod.png",
      "https://codeload.github.com/SCIInstitute/BrainStimulator/zip/master",
      "BrainStimulator_nightly.zip" };
    brainStimNightly.setupAction(actionBrainStimulatorNightly_, this);
  }
  connect(actionLoadToolkit_, SIGNAL(triggered()), this, SLOT(loadToolkit()));

  connect(networkEditor_, SIGNAL(networkExecuted()), networkProgressBar_.get(), SLOT(resetModulesDone()));
  connect(networkEditor_->moduleEventProxy().get(), SIGNAL(moduleExecuteEnd(double, const std::string&)), networkProgressBar_.get(), SLOT(incrementModulesDone(double, const std::string&)));
  connect(networkEditor_, SIGNAL(networkExecuted()), dialogErrorControl_.get(), SLOT(resetCounter()));
	connect(networkEditor_, SIGNAL(requestLoadNetwork(const QString&)), this, SLOT(checkAndLoadNetworkFile(const QString&)));
  connect(networkEditor_, SIGNAL(networkExecuted()), this, SLOT(changeExecuteActionIconToStop()));

  connect(prefsWindow_->actionTextIconCheckBox_, SIGNAL(clicked()), this, SLOT(adjustExecuteButtonAppearance()));
  prefsWindow_->actionTextIconCheckBox_->setCheckState(Qt::PartiallyChecked);
  adjustExecuteButtonAppearance();

  connect(networkEditor_, SIGNAL(newSubnetworkCopied(const QString&)), this, SLOT(updateClipboardHistory(const QString&)));
  connect(networkEditor_, SIGNAL(middleMouseClicked()), this, SLOT(switchMouseMode()));

  connect(openLogFolderButton_, SIGNAL(clicked()), this, SLOT(openLogFolder()));

  setupInputWidgets();

  logTextBrowser_->append("Hello! Welcome to SCIRun 5.");
  readSettings();

  setCurrentFile("");

  actionConfiguration_->setChecked(!configurationDockWidget_->isHidden());
  actionModule_Selector->setChecked(!moduleSelectorDockWidget_->isHidden());
  actionProvenance_->setChecked(!provenanceWindow_->isHidden());
  actionTriggeredEvents_->setChecked(!triggeredEventsWindow_->isHidden());
  actionTagManager_->setChecked(!tagManagerWindow_->isHidden());
  actionMiniview_->setChecked(!networkMiniViewDockWidget_->isHidden());

  moduleSelectorDockWidget_->setStyleSheet("QDockWidget {background: rgb(66,66,69); background-color: rgb(66,66,69) }"
	  "QToolTip { color: #ffffff; background - color: #2a82da; border: 1px solid white; }"
	  "QHeaderView::section { background: rgb(66,66,69);} "
	  );

  hideNonfunctioningWidgets();

  connect(moduleSelectorDockWidget_, SIGNAL(topLevelChanged(bool)), this, SLOT(updateDockWidgetProperties(bool)));

  setupVersionButton();

  WidgetStyleMixin::tabStyle(optionsTabWidget_);
}

const QString SCIRunMainWindow::saveFragmentData_("fragmentTree");

SCIRunMainWindow* SCIRunMainWindow::instance_ = nullptr;

SCIRunMainWindow* SCIRunMainWindow::Instance()
{
  if (!instance_)
  {
    instance_ = new SCIRunMainWindow;
  }
  return instance_;
}

SCIRunMainWindow::~SCIRunMainWindow()
{
  commandConverter_.reset();
  networkEditor_->disconnect();
  networkEditor_->setNetworkEditorController(nullptr);
  networkEditor_->clear();
  Application::Instance().shutdown();
}

void SCIRunMainWindow::executeCommandLineRequests()
{
  Application::Instance().executeCommandLineRequests();
}

void SCIRunMainWindow::networkTimedOut()
{
	exitApplication(2);
}

QString SCIRunMainWindow::strippedName(const QString& fullFileName)
{
  QFileInfo info(fullFileName);
  return info.fileName();
}

void SCIRunMainWindow::updateRecentFileActions()
{
  QMutableStringListIterator i(recentFiles_);
  while (i.hasNext()) {
    if (!QFile::exists(i.next()))
      i.remove();
  }

  for (int j = 0; j < MaxRecentFiles; ++j)
  {
    if (j < recentFiles_.count())
    {
      auto text = tr("&%1 %2")
        .arg(j + 1)
        .arg(strippedName(recentFiles_[j]));

      recentFileActions_[j]->setText(text);
      recentFileActions_[j]->setData(recentFiles_[j]);
      recentFileActions_[j]->setVisible(true);
    }
    else
    {
      recentFileActions_[j]->setVisible(false);
    }
  }
}

bool SCIRunMainWindow::okToContinue()
{
  if (isWindowModified()
		&& !Application::Instance().parameters()->isRegressionMode()
		&& !quitAfterExecute_
		&& !skipSaveCheck_)
  {
    int r = QMessageBox::warning(this, tr("SCIRun 5"), tr("The document has been modified.\n" "Do you want to save your changes?"),
      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
    if (QMessageBox::Yes == r)
    {
      saveNetwork();
      return true;
    }
    else if (QMessageBox::Cancel == r)
      return false;
  }
  return true;
}

QString SCIRunMainWindow::mostRecentFile() const
{
  return !recentFiles_.empty() ? recentFiles_[0] : "";
}

template <class T>
QString idFromPointer(T* item)
{
  QString addressString;
  QTextStream addressStream(&addressString);
  addressStream << static_cast<const void*>(item);
  addressStream.flush();
  return addressString;
}

void SCIRunMainWindow::setupSubnetItem(QTreeWidgetItem* fave, bool addToMap, const QString& idFromMap)
{
  auto id = addToMap ? idFromPointer(fave) + "::" + fave->text(0) : idFromMap;
  fave->setData(0, Qt::UserRole, id);

  if (addToMap)
  {
    savedSubnetworksXml_[id] = fave->data(0, clipboardKey).toString();
    savedSubnetworksNames_[id] = fave->text(0);
    fave->setFlags(fave->flags() & ~Qt::ItemIsEditable);
  }
}

void SCIRunMainWindow::printStyleSheet() const
{
  std::cout << "Printing style sheet details map" << std::endl;
  for (auto styleMapIt = styleSheetDetails_.constBegin(); styleMapIt != styleSheetDetails_.constEnd(); ++styleMapIt)
  {
    std::cout << "Style for: " << styleMapIt.key().toStdString() << std::endl;
    for (auto styleIt = styleMapIt.value().constBegin(); styleIt != styleMapIt.value().constEnd(); ++styleIt)
    {
      std::cout << "key: " << styleIt.key().toStdString() << " value: " << styleIt.value().toStdString() << std::endl;
    }
  }
}

void SCIRunMainWindow::showStatusMessage(const QString& str)
{
	statusBar()->showMessage(str);
}

void SCIRunMainWindow::showStatusMessage(const QString& str, int timeInMsec)
{
	statusBar()->showMessage(str, timeInMsec);
}

ext: cc


text:
#pragma once

/*
   Quick analysis to collect the set of variables and constants that might
   define array segment boundaries.
*/

#include <crab/cfg/cfg.hpp>
#include <crab/domains/discrete_domains.hpp>
#include <crab/iterators/killgen_fixpoint_iterator.hpp>
#include <crab/support/debug.hpp>
#include <crab/support/stats.hpp>

#include <boost/range/iterator_range.hpp>
#include <boost/unordered_map.hpp>

namespace crab {

namespace analyzer {

template <class CFG>
class array_segment_ops
    : public crab::iterators::killgen_operations_api<
      CFG, ikos::discrete_domain<typename CFG::variable_t>> {

  using killgen_operations_api_t = crab::iterators::killgen_operations_api<
      CFG, ikos::discrete_domain<typename CFG::variable_t>>;

public:
  using basic_block_label_t = typename CFG::basic_block_label_t;
  using N = typename CFG::number_t;
  using V = typename CFG::varname_t;
  using variable_t = typename CFG::variable_t;
  using array_segment_domain_t =
      typename killgen_operations_api_t::killgen_domain_t;

private:
  class array_segment_visitor
      : public crab::cfg::statement_visitor<basic_block_label_t, N, V> {
    using bin_op_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                           N, V>::bin_op_t;
    using assign_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                           N, V>::assign_t;
    using assume_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                           N, V>::assume_t;
    using select_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                           N, V>::select_t;
    using assert_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                           N, V>::assert_t;

    using havoc_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                          N, V>::havoc_t;
    using unreach_t = typename crab::cfg::statement_visitor<basic_block_label_t,
                                                            N, V>::unreach_t;
    using callsite_t =
        typename crab::cfg::statement_visitor<basic_block_label_t, N,
                                              V>::callsite_t;

    using arr_init_t =
        typename crab::cfg::statement_visitor<basic_block_label_t, N,
                                              V>::arr_init_t;
    using arr_load_t =
        typename crab::cfg::statement_visitor<basic_block_label_t, N,
                                              V>::arr_load_t;
    typedef typename crab::cfg::statement_visitor<basic_block_label_t, N,
                                                  V>::arr_store_t arr_store_t;

    // assume all statements have the same type expression_t;
    using linear_expression_t = typename bin_op_t::linear_expression_t;
    using linear_constraint_t = typename assume_t::linear_constraint_t;

    array_segment_domain_t get_variables(const linear_expression_t &e) const {
      array_segment_domain_t res;
      for (auto const &v : e.variables())
        res += v;
      return res;
    }

    array_segment_domain_t get_variables(const linear_constraint_t &c) const {
      array_segment_domain_t res;
      for (auto const &v : c.variables())
        res += v;
      return res;
    }

  public:
    array_segment_domain_t m_indexes;

    array_segment_visitor(array_segment_domain_t inv) : m_indexes(inv) {}

    void visit(bin_op_t &s) {
      if (!(m_indexes & s.lhs()).is_bottom()) {
        m_indexes += get_variables(s.left());
        m_indexes += get_variables(s.right());
      }
    }

    void visit(assign_t &s) {
      if (!(m_indexes & s.lhs()).is_bottom()) {
        m_indexes += get_variables(s.rhs());
      }
    }

    void visit(assume_t &s) {
      auto vars = get_variables(s.constraint());
      if (!(m_indexes & vars).is_bottom())
        m_indexes += vars;
    }

    void visit(arr_init_t &s) {
      m_indexes += get_variables(s.lb_index());
      m_indexes += get_variables(s.ub_index());
    }

    void visit(arr_load_t &s) { m_indexes += get_variables(s.index()); }

    void visit(arr_store_t &s) {
      m_indexes += get_variables(s.lb_index());
      m_indexes += get_variables(s.ub_index());
    }

    void visit(unreach_t &) {}

    // FIXME: implement these
    void visit(select_t &) {}
    void visit(callsite_t &) {}
    void visit(havoc_t &) {}
    void visit(assert_t &) {}
  };

public:
  array_segment_ops(CFG cfg) : killgen_operations_api_t(cfg) {}

  virtual bool is_forward() override { return false; }

  virtual std::string name() override { return "array_segment"; }

  virtual void init_fixpoint() override {}

  virtual array_segment_domain_t entry() override {
    return array_segment_domain_t::bottom();
  }

  virtual array_segment_domain_t merge(array_segment_domain_t d1,
                                       array_segment_domain_t d2) override {
    return d1 | d2;
  }

  virtual array_segment_domain_t analyze(const basic_block_label_t &bb_id,
                                         array_segment_domain_t in) override {
    auto &bb = this->m_cfg.get_node(bb_id);
    array_segment_visitor vis(in);
    for (auto &s : bb) {
      s.accept(&vis);
    }
    return vis.m_indexes;
  }
};

template<class CFG>
class array_segmentation : public crab::iterators::killgen_fixpoint_iterator<
                               CFG, array_segment_ops<CFG>> {
public:
  using array_segment_ops_t = array_segment_ops<CFG>;
  using basic_block_label_t = typename CFG::basic_block_label_t;
  using statement_t = typename CFG::statement_t;
  using varname_t = typename CFG::varname_t;
  using array_segment_domain_t =
      typename array_segment_ops_t::array_segment_domain_t;

private:
  using killgen_fixpoint_iterator_t =
      crab::iterators::killgen_fixpoint_iterator<CFG, array_segment_ops_t>;
  using segment_map_t =
      boost::unordered_map<basic_block_label_t, array_segment_domain_t>;

  segment_map_t m_segment_map;
  array_segment_ops_t m_array_segment_ops;

public:
  array_segmentation(CFG cfg)
    : killgen_fixpoint_iterator_t(cfg, m_array_segment_ops),
      m_array_segment_ops(cfg) {}

  array_segmentation(const array_segmentation<CFG> &o) = delete;
  array_segmentation<CFG> &operator=(const array_segmentation<CFG> &o) = delete;

  void exec() {
    this->run();

    CRAB_LOG("array-segment",
             crab::outs()
                 << "Array segment variables alive at the block entries\n";);

    for (auto p :
         boost::make_iterator_range(this->in_begin(), this->in_end())) {
      CRAB_LOG("array-segment", crab::outs()
                                    << p.first << ":" << p.second << "\n";);
      m_segment_map.insert(std::make_pair(p.first, p.second));
    }
    this->release_memory();
  }

  array_segment_domain_t get_variables(const basic_block_label_t &bb) const {
    auto it = m_segment_map.find(bb);
    if (it == m_segment_map.end())
      return array_segment_domain_t();
    else
      return it->second;
  }

  void write(crab_os &o) const {}
};

// Visitor for finding constants that might appear as array
// segment boundaries.
template <class CFG, class ArraySegmentDom>
class array_constant_segment_visitor
    : public crab::cfg::statement_visitor<typename CFG::basic_block_label_t,
                                          typename CFG::number_t,
                                          typename CFG::varname_t> {

  using BBL = typename CFG::basic_block_label_t;
  using N = typename CFG::number_t;
  using V = typename CFG::varname_t;
  using bin_op_t = typename crab::cfg::statement_visitor<BBL, N, V>::bin_op_t;
  using assign_t = typename crab::cfg::statement_visitor<BBL, N, V>::assign_t;
  using assume_t = typename crab::cfg::statement_visitor<BBL, N, V>::assume_t;
  using havoc_t = typename crab::cfg::statement_visitor<BBL, N, V>::havoc_t;
  using unreach_t = typename crab::cfg::statement_visitor<BBL, N, V>::unreach_t;
  using select_t = typename crab::cfg::statement_visitor<BBL, N, V>::select_t;
  using callsite_t =
      typename crab::cfg::statement_visitor<BBL, N, V>::callsite_t;
  using assert_t = typename crab::cfg::statement_visitor<BBL, N, V>::assert_t;

  using arr_init_t =
      typename crab::cfg::statement_visitor<BBL, N, V>::arr_init_t;
  using arr_load_t =
      typename crab::cfg::statement_visitor<BBL, N, V>::arr_load_t;
  using arr_store_t =
      typename crab::cfg::statement_visitor<BBL, N, V>::arr_store_t;

  using linear_expression_t = typename bin_op_t::linear_expression_t;
  using number_t = typename linear_expression_t::number_t;

public:
  using constant_set_t = std::vector<number_t>;

private:
  ArraySegmentDom m_dom;
  constant_set_t m_csts;

public:
  array_constant_segment_visitor(ArraySegmentDom dom) : m_dom(dom) {}

  constant_set_t get_constants() { return m_csts; }

  /// XXX: we focus for now only on assignments
  void visit(assign_t &s) {
    if (!(m_dom & s.lhs()).is_bottom()) {
      if (s.rhs().is_constant() && s.rhs().constant() >= 0 &&
          std::find(m_csts.begin(), m_csts.end(), s.rhs().constant()) ==
              m_csts.end()) {
        m_csts.push_back(s.rhs().constant());
        // for decrementing loops we need to include the upper bound index i and
        // i+1
        m_csts.push_back(s.rhs().constant() + 1);
      }
    }
  }

  void visit(bin_op_t &s) {}
  void visit(assume_t &s) {}
  void visit(arr_init_t &s) {}
  void visit(arr_load_t &s) {}
  void visit(arr_store_t &s) {}
  void visit(select_t &) {}
  void visit(callsite_t &) {}
  void visit(havoc_t &) {}
  void visit(assert_t &) {}
  void visit(unreach_t &) {}
};

} // end namespace analyzer
} // end namespace crab

ext: hpp

max_stars_repo_name: LinerSu/crab

max_issues_repo_name: LinerSu/crab

max_forks_repo_name: LinerSu/crab


text:
/**
 *-----------------------------------------------------------------------------
 * Title      : Rogue EPICS V3 Interface: Top Level Server
 * ----------------------------------------------------------------------------
 * File       : Server.cpp
 * Created    : 2018-02-12
 * ----------------------------------------------------------------------------
 * Description:
 * EPICS Server For Rogue System
 * ----------------------------------------------------------------------------
 * This file is part of the rogue software platform. It is subject to
 * the license terms in the LICENSE.txt file found in the top-level directory
 * of this distribution and at:
 *    https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
 * No part of the rogue software platform, including this file, may be
 * copied, modified, propagated, or distributed except according to the terms
 * contained in the LICENSE.txt file.
 * ----------------------------------------------------------------------------
**/

#include <rogue/protocols/epicsV3/Server.h>
#include <rogue/protocols/epicsV3/Value.h>
#include <rogue/protocols/epicsV3/Pv.h>
#include <rogue/protocols/epicsV3/Work.h>
#include <rogue/GilRelease.h>
#include <rogue/GeneralError.h>
#include <fdManager.h>

namespace rpe = rogue::protocols::epicsV3;

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/python.hpp>
namespace bp  = boost::python;

//! Setup class in python
void rpe::Server::setup_python() {

   bp::class_<rpe::Server, rpe::ServerPtr, boost::noncopyable >("Server",bp::init<uint32_t>())
      .def("_addValue", &rpe::Server::addValue)
      .def("_start",    &rpe::Server::start)
      .def("_stop",     &rpe::Server::stop)
   ;
}

//! Class creation
rpe::Server::Server (uint32_t count) : caServer(), running_(false) {
   workCnt_ = count;
   workersEn_ = false;
   threadEn_  = false;

   if ( count > 0 ) workers_ = (std::thread **)malloc(workCnt_ * sizeof(std::thread *));
   else workers_ = NULL;

   log_ = rogue::Logging::create("epicsV3.Server");
}

rpe::Server::~Server() {
   std::map<std::string, rpe::ValuePtr>::iterator it;

   stop();

   for ( it = values_.begin(); it != values_.end(); ++it ) {
      delete it->second->getPv();
      it->second.reset();
   }
   values_.clear();

   if ( workers_ != NULL ) free(workers_);
}

void rpe::Server::start() {
   uint32_t x;
   //this->setDebugLevel(10);

   log_->info("Starting epics server with %i workers",workCnt_);

   threadEn_ = true;
   thread_ = new std::thread(&rpe::Server::runThread, this);

   // Set a thread name
#ifndef __MACH__
   pthread_setname_np( thread_->native_handle(), "EpicsV3Server" );
#endif

   if ( workCnt_ > 0 ) {
      workersEn_ = true;
      for (x=0; x < workCnt_; x++)
         workers_[x] = new std::thread(boost::bind(&rpe::Server::runWorker, this));
   }
   running_ = true;
}

void rpe::Server::stop() {
   uint32_t x;

   log_->info("Stopping epics server");

   if (running_) {
      rogue::GilRelease noGil;

      for (x=0; x < workCnt_; x++)
         workQueue_.push(std::shared_ptr<rogue::protocols::epicsV3::Work>());

      workersEn_ = false;
      for (x=0; x < workCnt_; x++) workers_[x]->join();

      threadEn_ = false;
      thread_->join();
      running_ = false;
   }
}

void rpe::Server::addValue(rpe::ValuePtr value) {
   std::map<std::string, rpe::ValuePtr>::iterator it;
   rpe::Pv * pv;

   std::lock_guard<std::mutex> lock(mtx_);

   if ( (it = values_.find(value->epicsName())) == values_.end()) {
      pv = new Pv(this, value);
      value->setPv(pv);
      values_[value->epicsName()] = value;
   }
   else {
      throw rogue::GeneralError("Server::addValue","EPICs name already exists: " + value->epicsName());
   }
}

bool rpe::Server::doAsync() {
   return workersEn_;
}

void rpe::Server::addWork(rpe::WorkPtr work) {
   workQueue_.push(work);
}

pvExistReturn rpe::Server::pvExistTest(const casCtx &ctx, const char *pvName) {
   std::lock_guard<std::mutex> lock(mtx_);

   std::map<std::string, rpe::ValuePtr>::iterator it;

   if ( (it = values_.find(pvName)) == values_.end()) {
      return pverDoesNotExistHere;
   }
   else {
      return pverExistsHere;
   }
}

pvCreateReturn rpe::Server::createPV(const casCtx &ctx, const char *pvName) {
   std::lock_guard<std::mutex> lock(mtx_);

   std::map<std::string, rpe::ValuePtr>::iterator it;

   if ( (it = values_.find(pvName)) == values_.end())
      return S_casApp_pvNotFound;

   return *(it->second->getPv());
}

pvAttachReturn rpe::Server::pvAttach(const casCtx &ctx, const char *pvName) {
   std::lock_guard<std::mutex> lock(mtx_);

   std::map<std::string, rpe::ValuePtr>::iterator it;
   rpe::Pv * pv;

   if ( (it = values_.find(pvName)) == values_.end())
      return S_casApp_pvNotFound;

   return *(it->second->getPv());
}

//! Run thread
void rpe::Server::runThread() {

   log_->info("Starting epics server thread");
   log_->logThreadId();

   while(threadEn_) {
      try{
         fileDescriptorManager.process(0.01);
      } catch (...) {
         log_->error("Caught exception in server thread");
      }
   }
   log_->info("Stopping epics server thread");
}

//! Work thread
void rpe::Server::runWorker() {
   rpe::WorkPtr work;

   log_->info("Starting epics worker thread");
   log_->logThreadId();

   while(workersEn_) {
      work = workQueue_.pop();
      if (work == NULL) break;
      try{
         work->execute();
      } catch (...) {
         log_->error("Caught exception in worker thread");
      }
   }
}

ext: cpp

max_stars_repo_name: slacrherbst/rogue

max_issues_repo_name: slacrherbst/rogue

max_forks_repo_name: slacrherbst/rogue


text:
/*
 * MIT License
 *
 * Copyright (c) 2021 Dima Dorezyuk
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <dpose_core/dpose_costmap.hpp>

#include <boost/thread/lock_types.hpp>

#include <algorithm>
#include <array>
#include <cassert>
#include <iterator>
#include <map>
#include <memory>
#include <numeric>
#include <stdexcept>
#include <vector>

namespace dpose_core {

polygon
make_footprint(costmap_2d::LayeredCostmap &_cm) {
  const auto res = _cm.getCostmap()->getResolution();
  // resolution cannot be zero otherwise we get device by zero issues
  if (res <= 0)
    throw std::runtime_error("resolution must be positive");

  // convert the message to a eigen-polygon
  const auto fp = _cm.getFootprint();
  polygon cells(2, fp.size());
  for (int cc = 0; cc != cells.cols(); ++cc) {
    cells(0, cc) = std::round(fp.at(cc).x / res);
    cells(1, cc) = std::round(fp.at(cc).y / res);
  }
  return cells;
}

cell_vector
raytrace(const cell &_begin, const cell &_end) noexcept {
  // original code under raytraceLine in
  // https://github.com/ros-planning/navigation/blob/noetic-devel/costmap_2d/include/costmap_2d/costmap_2d.h
  const cell delta_raw = _end - _begin;
  const cell delta = delta_raw.array().abs();

  cell::Index row_major, row_minor;
  const auto den = delta.maxCoeff(&row_major);
  const auto add = delta.minCoeff(&row_minor);

  // this can happen if both are equal. then we can pick whats minor and whats
  // major.
  if (row_major == row_minor)
    row_minor = 1 - row_major;
  const auto size = den;

  assert(size >= 0 && "negative size detected");

  int num = den / 2;

  // setup the increments. note Eigen's signum returns zero if the argument is
  // zero.
  cell inc_minor = delta_raw.array().sign();
  cell inc_major = inc_minor;

  // erase the "other" row
  inc_minor(row_major) = 0;
  inc_major(row_minor) = 0;

  // allocate space beforehand
  cell_vector ray(size);
  cell curr = _begin;

  // bresenham's iteration
  for (int ii = 0; ii < size; ++ii) {
    ray.at(ii) = curr;

    num += add;
    if (num >= den) {
      num -= den;
      curr += inc_minor;
    }
    curr += inc_major;
  }

  return ray;
}

cell_rays
to_rays(const rectangle<int> &_rect) noexcept {
  cell_rays rays;
  for (int cc = 0; cc != 4; ++cc) {
    const auto ray = raytrace(_rect.col(cc), _rect.col(cc + 1));
    for (const auto &cell : ray)
      rays[cell.y()].extend(cell.x());
  }
  return rays;
}

cell_vector
lethal_cells_within(costmap_2d::Costmap2D &_map,
                    const rectangle<int> &_bounds) {
  // enforce that bounds is within costmap
  rectangle<int> search_box = _bounds.array().max(0).matrix();

  // check if size is zero to prevent underflow
  if (_map.getSizeInCellsX() == 0 || _map.getSizeInCellsY() == 0)
    return {};

  // clang-format off
  search_box.row(0) = search_box.row(0).array().min(_map.getSizeInCellsX() - 1).matrix();
  search_box.row(1) = search_box.row(1).array().min(_map.getSizeInCellsY() - 1).matrix();
  // clang-format on

  // first swipe to count the number of elements
  const auto rays = to_rays(search_box);

  size_t count = 0;

  // lock the costmap
  boost::unique_lock<boost::recursive_mutex> lock(*_map.getMutex());
  const auto char_map = _map.getCharMap();

  // counting first the lethal cells and then writing them into the cell_vector
  // is for the given perf-measurement the fastest way to go.
  for (const auto &ray : rays) {
    const auto &y = ray.first;
    // debug-asserts on the indices
    assert(y >= 0 && "y index cannot be negative");
    assert(y < _map.getSizeInCellsY() && "y index out of bounds");
    assert(ray.second.min >= 0 && "x index cannot be negative");
    assert(ray.second.max < _map.getSizeInCellsX() && "x index out of bounds");

    const auto ii_end = _map.getIndex(ray.second.max + 1, y);
    // branchless formulation of "if(char_map[ii] == _value) {++count;}"
    for (auto ii = _map.getIndex(ray.second.min, y); ii != ii_end; ++ii)
      count += (char_map[ii] == costmap_2d::LETHAL_OBSTACLE);
  }

  if (!count)
    return {};

  // resize the final vector
  cell_vector cells(count);

  // dd is the index of the "destination" (where to write to)
  auto dd_iter = cells.begin();

  // write the cells
  for (const auto &ray : rays) {
    const auto &y = ray.first;
    // the conversion to x-value from index is x = index - (y * x_size). the
    // y_offset is here the second part of the equation.
    const auto y_offset = y * _map.getSizeInCellsX();
    const auto ii_end = _map.getIndex(ray.second.max + 1, y);

    // as in the first swipe, but now we convert the index to cells
    for (auto ii = _map.getIndex(ray.second.min, y); ii != ii_end; ++ii) {
      if (char_map[ii] == costmap_2d::LETHAL_OBSTACLE)
        *dd_iter++ = {ii - y_offset, y};
    }
  }

  assert(dd_iter == cells.end() && "bad index: dd_iter");

  return cells;
}

bool
is_inside(const costmap_2d::Costmap2D &_map,
          const polygon &_footprint) noexcept {
  // get the size of the costmap
  const Eigen::Array2i size(_map.getSizeInCellsX(), _map.getSizeInCellsY());

  const int cols = _footprint.cols();
  for (int cc = 0; cc != cols; ++cc) {
    const Eigen::Array2i point = _footprint.col(cc).array();
    if ((point < 0).any() || (point >= size).any())
      return false;
  }
  return true;
}

namespace bresenham {

base_iterator::base_iterator(const cell &_begin, const cell &_end) noexcept {
  const Eigen::Array2i diff = _end - _begin;

  // init the common members. the naming follows the naming of raytrace.
  x_sign = diff.sign().x();
  den = diff.abs().maxCoeff();
  add = diff.abs().minCoeff();

  // some checks
  assert(den >= 0);
  assert(add >= 0);
  assert(den >= add);

  num = den / 2;
  dx = static_cast<double>(diff.x()) / diff.y();
}

x_minor_ascending::x_minor_ascending(const cell &_begin, const cell &_end) :
    base_iterator(_begin, _end) {
  x_curr = _begin.x();
}

x_minor_ascending &
x_minor_ascending::operator++() noexcept {
  num += add;
  if (num >= den) {
    num -= den;
    x_curr += x_sign;
  }

  assert(num < den && "bresenham failed");
  return *this;
}

x_minor_descending::x_minor_descending(const cell &begin, const cell &end) :
    base_iterator(end, begin) {
  x_curr = begin.x();
}

x_minor_descending &
x_minor_descending::operator++() noexcept {
  num -= add;
  if (num < 0) {
    num += den;
    x_curr -= x_sign;
  }

  assert(num >= 0 && "bresenham failed");
  return *this;
}

x_major_ascending::x_major_ascending(const cell &_begin, const cell &_end) :
    base_iterator(_begin, _end) {
  x_curr = _begin.x();
}

x_major_ascending &
x_major_ascending::operator++() noexcept {
  const int diff = den - num;
  const int step = diff / add;
  num += (step * add);
  x_curr += (step * x_sign);
  // check if we need to add another step to reach den
  if (num < den) {
    num += add;
    x_curr += x_sign;
  }

  assert(num >= den && "logic error");
  num -= den;
  assert(num < den && "logic error");
  return *this;
}

x_major_descending::x_major_descending(const cell &begin, const cell &end) :
    base_iterator(end, begin) {
  x_curr = begin.x();
}

x_major_descending &
x_major_descending::operator++() noexcept {
  assert(den >= add && "den cannot be smaller then add");

  const int step = num / add;
  num -= (step * add);
  x_curr -= (step * x_sign);
  // check if we need to add another step to reach negative numbers
  if (num >= 0) {
    num -= add;
    x_curr -= x_sign;
  }

  assert(num < 0 && "logic error");
  num += den;
  assert(num > 0 && "logic error");
  return *this;
}

}  // namespace bresenham

x_bresenham::x_bresenham(const cell &_c0, const cell &_c1) noexcept {
  const cell diff = (_c1 - _c0).array().abs();
  if (diff.x() > diff.y()) {
    if (_c1.y() > _c0.y())
      impl_ = std::make_unique<bresenham::x_major_ascending>(_c0, _c1);
    else
      impl_ = std::make_unique<bresenham::x_major_descending>(_c1, _c0);
  }
  else {
    if (_c1.y() > _c0.y())
      impl_ = std::make_unique<bresenham::x_minor_ascending>(_c0, _c1);
    else
      impl_ = std::make_unique<bresenham::x_minor_descending>(_c1, _c0);
  }
}

struct line : public x_bresenham {
  line(const cell &_begin, const cell &_end) :
      lower(_begin), upper(_end), x_bresenham(_begin, _end) {}
  cell lower, upper;
  bool active = false;
};

struct lines_compare {
  inline bool
  operator()(const line *_l1, const line *_l2) const noexcept {
    if (_l1->get_x() != _l2->get_x())
      return _l1->get_x() < _l2->get_x();

    return _l1->get_dx() < _l2->get_dx();
  }
};

using lines_set = std::vector<line *>;

/**
 * @brief helper function for the scan-line algorithm.
 *
 * Function iterates over the _maps cells within a scan-line defined by the
 * index yy. It returns true, if no cell has the value _cost.
 *
 * @param _map The costmap.
 * @param _lines Currently active lines. The size must be even.
 * @param yy The index of the scan-line
 * @param _cost The searched cost.
 */
bool
check_line(const costmap_2d::Costmap2D &_map, const lines_set &_lines, int yy,
           uint8_t _cost) {
  // check the input quality - we need an even size because we swipe between the
  // left and right lines.
  assert(_lines.size() % 2 == 0 && "lines.size() must be even");

  // iterate pair-wise within the active-lines. the active lines are sorted
  // by the x-value.
  auto raw_map = _map.getCharMap();
  for (auto l_line = _lines.begin(); l_line != _lines.end();
       std::advance(l_line, 2)) {
    const auto r_line = std::next(l_line);
    // get the x-values
    const int l_x = (*l_line)->get_x() + 1;
    const int r_x = (*r_line)->get_x();

    if (l_x >= r_x)
      continue;

    // swipe through the raw costmap.
    const auto r_index = raw_map + _map.getIndex(r_x, yy);
    auto l_index = raw_map + _map.getIndex(l_x, yy);
    for (; l_index != r_index; ++l_index) {
      if (*l_index == _cost)
        return false;
    }
  }
  return true;
}

/**
 * @brief implements a check if a line or point footprint covers a cell with the
 * value _cost.
 *
 * The _footprint must have less then three vertices: it may be empty, a point
 * or a line. The function will check if any cell covered by the footprint has
 * the value _cost. If such cell exists, it returns false.
 *
 * @param _map The costmap.
 * @param _footprint The footprint (defined by vertices in cell coordinates).
 * @param _cost The interesting cost.
 */
bool
check_without_area(const costmap_2d::Costmap2D &_map, const polygon &_footprint,
                   uint8_t _cost) noexcept {
  // get the number of vertices
  const auto cols = _footprint.cols();

  // setup the check lambda
  auto is_good = [&](const cell __cell) {
    return _map.getCost(__cell.x(), __cell.y()) != _cost;
  };

  switch (cols) {
    case 0: {
      // an empty footprint
      return true;
    }
    case 1: {
      // a point-footprint
      return is_good(_footprint.col(0));
    }
    case 2: {
      // a line-footprint
      const auto cells = raytrace(_footprint.col(0), _footprint.col(1));
      return std::all_of(cells.begin(), cells.end(), is_good);
    }
    default: {
      assert(false && "footprint defines an area");
      return false;
    }
  }
}

/**
 * @brief checks the outline of the _footprint
 *
 * @param _map The costmap.
 * @param _footprint The footprint (closed or opened).
 * @param _cost The cost we are looking after.
 * @return true, if the outline does not contain a cell with _cost.
 */
bool
check_outline(const costmap_2d::Costmap2D &_map, const polygon &_footprint,
              uint8_t _cost) {
  // get the number of vertices
  const auto cols = _footprint.cols();
  assert(cols > 2 && "no outline defined");

  // setup the check lambda
  auto is_good = [&](const cell __cell) {
    return _map.getCost(__cell.x(), __cell.y()) != _cost;
  };

  for (int ii = 1; ii < cols; ++ii) {
    const auto ray = raytrace(_footprint.col(ii - 1), _footprint.col(ii));
    if (!std::all_of(ray.begin(), ray.end(), is_good))
      return false;
  }

  // the footprint might be closed. in this case we can skip the last vertex,
  // since it does not add any information.
  const auto is_closed = _footprint.col(cols - 1) == _footprint.col(0);
  if (!is_closed) {
    const auto ray = raytrace(_footprint.col(cols - 1), _footprint.col(0));
    return std::all_of(ray.begin(), ray.end(), is_good);
  }
  return true;
}

bool
check_footprint(const costmap_2d::Costmap2D &_map, const polygon &_footprint,
                uint8_t _cost) {
  // check if all vertices are within the costmap
  if (!is_inside(_map, _footprint))
    return false;

  const auto cols = _footprint.cols();
  // if we have less then tree vertices we don't have an area defined.
  if (cols < 3)
    return check_without_area(_map, _footprint, _cost);

  // we check the outline seperated, since we have to pay attention to the
  // discretization issues.
  if (!check_outline(_map, _footprint, _cost))
    return false;

  // we are now certain that we have a polygon and will
  // implement the scan-line algorithm below.

  // the footprint might be closed. in this case we can skip the last vertex,
  // since it does not add any information.
  const auto is_closed = _footprint.col(cols - 1) == _footprint.col(0);

  // convert the footprint into lines. a line is defined by two adjacent
  // vertices. assume we have the vertices [a, b, c] (or the closed variant [a,
  // b, c, a]). our edges will be [[a, b], [b, c], [c, a]].
  std::vector<line> lines;
  lines.reserve(cols - is_closed);
  for (int cc = 1; cc != cols; ++cc) {
    // the scan-line algorithm is allergic to horizontal lines; so we skip them.
    if (_footprint(1, cc - 1) != _footprint(1, cc))
      lines.emplace_back(_footprint.col(cc - 1), _footprint.col(cc));
  }
  if (!is_closed && _footprint(1, cols - 1) != _footprint(1, 0))
    lines.emplace_back(_footprint.col(cols - 1), _footprint.col(0));

  // create a map of the vertices mapping the y-value of vertex to its two
  // adjacent edges. assume we have the vertices [a, b, c] and have generated
  // the edges [[a, b], [b, c], [c, a]] which we call [A, B, C]. our map then
  // contains {a.y: [C, A], b.y: [A, B], c.y: [B, C]}.
  using vertex = std::array<line *, 2>;
  std::multimap<int, vertex> vertex_set;
  for (auto l_line = lines.begin(), r_line = std::next(l_line);
       r_line != lines.end(); ++l_line, ++r_line) {
    vertex_set.emplace(r_line->lower.y(), vertex{&(*l_line), &(*r_line)});
  }
  vertex_set.emplace(lines.front().lower.y(),
                     vertex{&lines.back(), &lines.front()});

  // as typical in scan-line algorithm we maintian a set of active lines: the
  // lines are intersected by the current y-value. we sort them by their lowest
  // x-value.
  lines_set active_lines;

  // init the scan-line below the lowerst y-value.
  auto yy = _footprint.row(1).minCoeff() - 1;

  // assume our vertice are [a, b, c]. as above we denote the edges [[a, b], [b,
  // c], [c, a]] as [A, B, C]. the vertices shall have the following coordinates
  // - a: (0, 0)
  // - b: (5, 2)
  // - c: (-1, 3)
  // our yy denotes the current y-value of the scan line and  will range from
  // [-1 ,3]. the vertex_set is  {a.y: [C, A], b.y: [A, B], c.y: [B, C]}. v_next
  // will be the next vertex we can reach.
  // yy = -1:
  //    active_lines: []
  //    v_next: a (with a.y = 0)
  // yy = 0:
  //    active_lines [] -> [A, C]
  //    v_next: b (with b.y = 2)
  // yy = 1:
  //    active_lines [A, C]
  //    v_next: b (with b.y = 2)
  // yy = 2
  //    active_lines [A, C] -> [C, B]
  //    v_next: c (with c.y = 3)
  // yy = 3
  //    active_lines [A, C] -> []
  //    v_next: end

  // iterate over all vertices
  for (auto v_next = vertex_set.begin(); v_next != vertex_set.end();) {
    // our active line set changes only on vertices. we can hence use the
    // current line set until we reach the next vertex.
    for (; yy < v_next->first; ++yy) {
      if (!check_line(_map, active_lines, yy, _cost))
        return false;

      // advance the lines
      for (auto &l : active_lines)
        l->advance_x();
    }

    // we have reached the v_next. we remove ending lines form and add new
    // lines to the active_lines. we iterate until we reach a vertex with a
    // bigger y value, since multiple vertices may be located at the current
    // scan line.
    for (; v_next != vertex_set.end() && v_next->first == yy; ++v_next) {
      // check the two lines of the current vertex
      for (const auto &line : v_next->second) {
        // a line starts, if both if its vertices are equal or above the current
        // scan-line.
        if (line->active) {
          auto iter = std::find(active_lines.begin(), active_lines.end(), line);
          assert(iter != active_lines.end() && "line not found");
          // swap and pop - we don't care much for the order since we will sort
          // the vertices again.
          std::iter_swap(iter, std::prev(active_lines.end()));
          active_lines.pop_back();
        }
        else {
          line->active = true;
          active_lines.emplace_back(line);
        }
      }
    }
    // reorder the active lines after we have changed them
    std::sort(active_lines.begin(), active_lines.end(), lines_compare{});
  }
  return true;
}

}  // namespace dpose_core

max_stars_repo_name: dorezyuk/dpose

max_issues_repo_name: dorezyuk/dpose

max_forks_repo_name: dorezyuk/dpose


text:
#ifndef TELEMETRYWIDGET_HPP
#define TELEMETRYWIDGET_HPP

#include "engine.hpp"

#include <boost/optional.hpp>

#include <QWidget>

class QGroupBox;
class QPushButton;
class QLCDNumber;

class TelemetryWidget : public QWidget
{
	Q_OBJECT
public:
	explicit TelemetryWidget(QWidget* parent_ = 0);

private:
	boost::optional<std::reference_wrapper<const Engine>> m_engine;

	QPushButton* m_start_stop_button;
	QLCDNumber* m_altitude_lcd;
	QLCDNumber* m_speed_lcd;
	QLCDNumber* m_acceleration_lcd;
	QLCDNumber* m_time_lcd;

	QGroupBox* createGroupBoxFlightValues();

public
slots:
	void setEngine(const Engine& engine);

	/**
	 * @brief updateWidgets
	 * @preconditions m_engine is valid
	 */
	void updateWidgets();

	void disable();
	void enable();

signals:
	void start();
	void stop();

private
slots:
	void onStartStopButtonClicked();
};

#endif // TELEMETRYWIDGET_HPP

max_stars_repo_name: julienlopez/QRocketLaunchSimulator

max_issues_repo_name: julienlopez/QRocketLaunchSimulator

max_forks_repo_name: julienlopez/QRocketLaunchSimulator


text:
/****************************************************************************/
/* Copyright 2005-2006, Francis Russell                                     */
/*                                                                          */
/* Licensed under the Apache License, Version 2.0 (the License);            */
/* you may not use this file except in compliance with the License.         */
/* You may obtain a copy of the License at                                  */
/*                                                                          */
/*     http://www.apache.org/licenses/LICENSE-2.0                           */
/*                                                                          */
/* Unless required by applicable law or agreed to in writing, software      */
/* distributed under the License is distributed on an AS IS BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and      */
/* limitations under the License.                                           */
/*                                                                          */
/****************************************************************************/

#ifndef DESOLA_LITERAL_HPP
#define DESOLA_LITERAL_HPP

#include <cassert>
#include <cstddef>
#include <boost/scoped_ptr.hpp>
#include <boost/static_assert.hpp>
#include <desola/Desola_fwd.hpp>

namespace desola
{

namespace detail
{

template<typename exprType, typename T_element>
class Literal : public ExprNode<exprType, T_element>
{
  // Never instantiate
  BOOST_STATIC_ASSERT(sizeof(T_element)==0);
};

template<typename T_element>
class Literal<scalar, T_element> : public ExprNode<scalar, T_element>
{
protected:
  boost::scoped_ptr< InternalScalar<T_element> > value;

  virtual void update(ExprNode<scalar, T_element>& previous, ExprNode<scalar, T_element>& next) {}
  virtual void update(ExprNode<vector, T_element>& previous, ExprNode<vector, T_element>& next) {}
  virtual void update(ExprNode<matrix, T_element>& previous, ExprNode<matrix, T_element>& next) {}

public:
  Literal(InternalScalar<T_element>* const val) : value(val)
  {
    assert(val != NULL);
  }

  InternalScalar<T_element>& getValue()
  {
    return *value;
  }

  void accept(ExpressionNodeVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  void accept(LiteralVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  virtual void internal_evaluate()
  {
    // We don't do anything for literals
  }

  virtual T_element getElementValue()
  {
    return value->getElementValue();
  }

  virtual Maybe<double> getFlops() const
  {
    return 0.0;
  }
};

template<typename T_element>
class Literal<vector, T_element> : public ExprNode<vector, T_element>
{
protected:
  boost::scoped_ptr< InternalVector<T_element> > value;

  virtual void update(ExprNode<scalar, T_element>& previous, ExprNode<scalar, T_element>& next) {}
  virtual void update(ExprNode<vector, T_element>& previous, ExprNode<vector, T_element>& next) {}
  virtual void update(ExprNode<matrix, T_element>& previous, ExprNode<matrix, T_element>& next) {}

  inline static const boost::array<std::size_t, 1> getDimensions(const InternalVector<T_element>& internal)
  {
    const boost::array<std::size_t, 1> dims = { {internal.getRowCount()} };
    return dims;
  }

public:
  Literal(InternalVector<T_element>* const val) : ExprNode<vector, T_element>(getDimensions(*val)), value(val)
  {
    assert(val != NULL);
  }

  InternalVector<T_element>& getValue()
  {
    return *value;
  }

  void accept(ExpressionNodeVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  void accept(LiteralVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  virtual void internal_evaluate()
  {
    // We don't do anything for literals
  }

  virtual T_element getElementValue(const ElementIndex<vector>& index)
  {
    return value->getElementValue(index);
  }

  virtual Maybe<double> getFlops() const
  {
    return 0.0;
  }
};

template<typename T_element>
class Literal<matrix, T_element> : public ExprNode<matrix, T_element>
{
protected:
  boost::scoped_ptr< InternalMatrix<T_element> > value;

  virtual void update(ExprNode<scalar, T_element>& previous, ExprNode<scalar, T_element>& next) {}
  virtual void update(ExprNode<vector, T_element>& previous, ExprNode<vector, T_element>& next) {}
  virtual void update(ExprNode<matrix, T_element>& previous, ExprNode<matrix, T_element>& next) {}

  inline static const boost::array<std::size_t, 2> getDimensions(const InternalMatrix<T_element>& internal)
  {
    const boost::array<std::size_t, 2> dims = { {internal.getRowCount(), internal.getColCount()} };
    return dims;
  }

public:
  Literal(InternalMatrix<T_element>* const val) : ExprNode<matrix, T_element>(getDimensions(*val)), value(val)
  {
    assert(val != NULL);
  }

  InternalMatrix<T_element>& getValue()
  {
    return *value;
  }

  void accept(ExpressionNodeVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  void accept(LiteralVisitor<T_element>& v)
  {
    v.visit(*this);
  }

  virtual void internal_evaluate()
  {
    // We don't do anything for literals
  }

  virtual T_element getElementValue(const ElementIndex<matrix>& index)
  {
    return value->getElementValue(index);
  }

  virtual Maybe<double> getFlops() const
  {
    return 0.0;
  }

  virtual Maybe<std::size_t> nnz() const
  {
    return value->nnz();
  }
};

}

}
#endif

max_stars_repo_name: FrancisRussell/desola

max_issues_repo_name: FrancisRussell/desola

max_forks_repo_name: FrancisRussell/desola


text:
//==================================================================================================
/**
  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
**/
//==================================================================================================
#include <boost/simd/function/split.hpp>
#include <boost/simd/pack.hpp>
#include <simd_test.hpp>

namespace bs = boost::simd;
namespace bd = boost::dispatch;
namespace tt = nsm::type_traits;

template<typename T, std::size_t N, typename Env>
void test( Env&, tt::false_type const& )
{}

template<typename T, std::size_t N, typename Env>
void test( Env& runtime, tt::true_type const& )
{
  using type = bd::upgrade_t<T>;

  std::array<T,N> data;
  for(std::size_t i=0;i<data.size();++i)  data[i] = T(1+i);

  std::array<type,N> dref;
  for(std::size_t i=0;i<dref.size();++i)  dref[i] = static_cast<type>(data[i]);

  bs::pack<T,N>                 value (&data[0]     , &data[0]+N    );
  bd::upgrade_t<bs::pack<T,N>>  valuel, valueh;
  bd::upgrade_t<bs::pack<T,N>>  refl  (&dref[0]     , &dref[0]+N/2  );
  bd::upgrade_t<bs::pack<T,N>>  refh  (&dref[0]+N/2 , &dref[0]+N    );

  auto values = bs::split(value);

  STF_EQUAL( values[0] , refl);
  STF_EQUAL( values[1] , refh);
}

STF_CASE_TPL("split pack<T,N> into a pair of pack<T*2,N/2>", STF_NUMERIC_TYPES)
{
  static const std::size_t N = bs::pack<T>::static_size;

  test<T,N  >(runtime, bd::is_upgradable< bs::pack<T,N/2> >{});
  test<T,N/2>(runtime, bd::is_upgradable< bs::pack<T,N/2> >{});
  test<T,N*2>(runtime, bd::is_upgradable< bs::pack<T,N/2> >{});
}


text:
#include "rnnlm.h"

#include "math-utils.h"

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace dynet;
using namespace boost::program_options;

unsigned LAYERS = 2;
unsigned INPUT_DIM = 256;
unsigned HIDDEN_DIM = 512;
unsigned BATCH_SIZE = 1;
unsigned VOCAB_SIZE = 0;
unsigned ETA_EPOCH = 0;
unsigned MAX_EPOCH = 20;
dynet::real LAMBDA;
dynet::real ETA = 0.1f;
dynet::real ETA_DECAY = 2;
unsigned TREPORT = 20;
unsigned DREPORT = 200;
double MAX_LOSS = 9e+99;

dynet::Dict d;// vocabulary

bool verbose = false;

typedef std::vector<int> Sentence;
typedef std::vector<Sentence> Corpus;

Corpus Read_Corpus(const string &fp, bool dir=true);

inline size_t CalcSize(const Sentence & src, int trg);
inline void Create_MiniBatches(const Corpus& traincor, size_t max_size,
	std::vector<std::vector<Sentence> > & traincor_minibatch);

template <class RNNLM_t>
void TrainModel(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd
	, const string& param_file, float dropout_p);
template <class RNNLM_t>
void TrainModel_Batch1(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd
	, const string& param_file, float dropout_p);
template <class RNNLM_t>
void TrainModel_Batch2(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd
	, const string& param_file, float dropout_p);

template <class RNNLM_t>
void TestModel(Model &model, RNNLM_t &rnn
	, const Corpus &testcor);

template <class Builder>
int main_body(variables_map vm);

// Sort in descending order of length
struct CompareLen {
	bool operator()(const std::vector<int>& first, const std::vector<int>& second) {
		return first.size() > second.size();
	}
};

int main(int argc, char** argv) {
	dynet::initialize(argc, argv);

	// command line processing
	using namespace boost::program_options;
	variables_map vm;
	options_description opts("Allowed options");
	opts.add_options()
		("help", "print help message")
		("train,t", value<string>(), "file containing training sentences")
		("dev,d", value<string>(), "file containing development sentences")
		("test,T", value<string>(), "file containing testing source sentences for computing perplexity scores")
		("lang", value<bool>()->default_value(true), "use source or target language from a corpus, e.g., source ||| target")
		("initialise,l", value<string>(), "load initial parameters from file")
		("parameters,s", value<string>(), "save best parameters to this file")
		("layers", value<unsigned>()->default_value(LAYERS), "use <num> layers for RNN components")
		("hidden_dim,h", value<unsigned>()->default_value(HIDDEN_DIM), "use <num> dimensions for recurrent hidden states")
		("input_dim,i", value<unsigned>()->default_value(INPUT_DIM), "use <num> dimensions for input embedding")
		("batch_size,b", value<unsigned>()->default_value(BATCH_SIZE), "impose mini-batch size for training")
		("gru", "use Gated Recurrent Unit (GRU) for recurrent structure; default RNN")
		("lstm", "use Long Short Term Memory (LSTM) for recurrent structure; default RNN")
		("vlstm", "use Vanilla Long Short Term Memory (VLSTM) for recurrent structure; default RNN")
		("dglstm", "use Depth-Gated Long Short Term Memory (DGLSTM) for recurrent structure; default RNN")
		("dropout", value<float>(), "apply dropout technique (Gal et al., 2015) for RNN")
		("sgd_trainer", value<unsigned>()->default_value(0), "use specific SGD trainer (0: vanilla SGD; 1: momentum SGD; 2: Adagrad; 3: AdaDelta; 4: Adam)")
		("sparse_updates", value<bool>()->default_value(true), "enable/disable sparse update(s) for lookup parameter(s)")
		("r2l_target", "use right-to-left direction for target during training; default not")
		("max_loss", value<double>()->default_value(MAX_LOSS), "impose max loss if possible (for interruped running jobs)")
		("treport", value<unsigned>()->default_value(TREPORT), "impose instance reporting value (during training); default 50")
		("dreport", value<unsigned>()->default_value(DREPORT), "impose instance reporting value (during training) on development/test sets; default 500")
		("eta_epoch", value<unsigned>()->default_value(ETA_EPOCH), "limit number of epochs for scheduling the learning rate, e.g., decreasing by a factor of eta_decay; default 4")
		("max_epoch", value<unsigned>()->default_value(MAX_EPOCH), "limit number of epochs for training; default 20")
		("lambda", value<dynet::real>()->default_value(1e-6), "the L2 regularization coefficient; default 1e-6.")
		("eta", value<dynet::real>()->default_value(ETA), "the learning rate of neural network model; default 0.1")
		("eta_decay", value<dynet::real>()->default_value(ETA_DECAY), "decay value for decreasing the learning rate; default 2.")
		("seed", value<unsigned>()->default_value(1), "value for random initialization; default 1")
		("verbose,v", "be extremely noisy");

	store(parse_command_line(argc, argv, opts), vm);

	notify(vm);

	verbose = vm.count("verbose");
	ETA_EPOCH = vm["eta_epoch"].as<unsigned>();
	MAX_EPOCH = vm["max_epoch"].as<unsigned>();
	MAX_LOSS = vm["max_loss"].as<double>();
	TREPORT = vm["treport"].as<unsigned>();
	DREPORT = vm["dreport"].as<unsigned>();
	LAMBDA = vm["lambda"].as<dynet::real>();
	ETA_DECAY = vm["eta_decay"].as<dynet::real>();
	ETA = vm["eta"].as<dynet::real>();
	LAYERS = vm["layers"].as<unsigned>();
	INPUT_DIM = vm["input_dim"].as<unsigned>();
	HIDDEN_DIM = vm["hidden_dim"].as<unsigned>();

	if (vm.count("help")
		|| vm.count("train") != 1
		|| (vm.count("devel") != 1
			&& !(vm.count("test") == 0))) {
		cout << opts << "\n";
			return 1;
	}

	cerr << "PID=" << ::getpid() << endl;

	if (vm.count("lstm"))
		return main_body<LSTMBuilder>(vm);
	else if (vm.count("vlstm"))
		return main_body<VanillaLSTMBuilder>(vm);
	else if (vm.count("dglstm"))
		return main_body<DGLSTMBuilder>(vm);
   	else if (vm.count("gru"))
		return main_body<GRUBuilder>(vm);
   	else
		return main_body<SimpleRNNBuilder>(vm);
}

template <class Builder>
int main_body(variables_map vm)
{
	Corpus traincor, devcor, testcor;
	cerr << "Reading training data from " << vm["train"].as<string>() << "...\n";
	kSOS = d.convert("<s>");
	kEOS = d.convert("</s>");
	kUNK = d.convert("<unk>");
	traincor = Read_Corpus(vm["train"].as<string>(), vm["lang"].as<bool>());
	d.freeze(); // no new word types allowed

	VOCAB_SIZE = d.size();

	if (vm.count("dev")) {
		cerr << "Reading development data from " << vm["dev"].as<string>() << "...\n";
		devcor = Read_Corpus(vm["dev"].as<string>(), vm["lang"].as<bool>());
	}

	if (vm.count("test")){
		cerr << "Reading testing data from " << vm["test"].as<string>() << "...\n";
		testcor = Read_Corpus(vm["test"].as<string>(), vm["lang"].as<bool>());
	}

	float dropout_p = 0.0f;
	if (vm.count("dropout"))//apply dropout technique
	{
		dropout_p = vm["dropout"].as<float>();
		cerr << "Applying dropout technique with dropout probability p=" << dropout_p << "..." << endl;
	}

	string param_file = "";
	if (vm.count("parameters"))
		param_file = vm["parameters"].as<string>();
	else if (vm.count("initialise"))
		param_file = vm["initialise"].as<string>();
	else {
		ostringstream os;
		os << "rnnlm" << '_' << LAYERS << '_' << HIDDEN_DIM << '_' << INPUT_DIM << '_' << VOCAB_SIZE  << "_pid" << getpid() << ".params";
		param_file = os.str();
	}
	cerr << "Parameters will be updated to: " << param_file << endl;

	BATCH_SIZE = vm["batch_size"].as<unsigned>();

	Model model;
	unsigned sgd_trainer_type = vm["sgd_trainer"].as<unsigned>();
	Trainer* sgd_trainer = nullptr;
	if (sgd_trainer_type == 1)
		sgd_trainer = new MomentumSGDTrainer(model, vm["eta"].as<float>());
	else if (sgd_trainer_type == 2)
		sgd_trainer = new AdagradTrainer(model, vm["eta"].as<float>());
	else if (sgd_trainer_type == 3)
		sgd_trainer = new AdadeltaTrainer(model);
	else if (sgd_trainer_type == 4)
		sgd_trainer = new AdamTrainer(model, vm["eta"].as<float>());
	else if (sgd_trainer_type == 0)//Vanilla SGD trainer
		sgd_trainer = new SimpleSGDTrainer(model, vm["eta"].as<float>());
	else
		assert("Unknown SGD trainer type! (0: vanilla SGD; 1: momentum SGD; 2: Adagrad; 3: AdaDelta; 4: Adam)");
	sgd_trainer->eta_decay = ETA_DECAY;
	sgd_trainer->sparse_updates_enabled = vm["sparse_updates"].as<bool>();
	if (!sgd_trainer->sparse_updates_enabled)
		cerr << "Sparse updates for lookup parameter(s) to be disabled!" << endl;
	sgd_trainer->clip_threshold *= BATCH_SIZE;

	if (vm.count("r2l_target")) cerr << "Using right-to-left direction..." << endl;

	RNNLanguageModel<Builder> lm;
	if (vm.count("initialise"))// load from pre-trained model
		lm.LoadModel(&model, vm["initialise"].as<string>());
	else// create new model
		lm.CreateModel(&model, LAYERS, INPUT_DIM, HIDDEN_DIM, VOCAB_SIZE, vm.count("r2l_target"));

	if (vm.count("test")){
		TestModel(model, lm, testcor);
	}// otherwise, do training.
	else
		TrainModel_Batch2(model, lm, traincor, devcor, sgd_trainer, param_file, dropout_p);

	// cleaning up
	delete sgd_trainer;

	return EXIT_SUCCESS;
}

//====================================== FUNCTION IMPLEMENTATION ======================================

template <class RNNLM_t>
void TestModel(Model &model, RNNLM_t &rnn
	, const Corpus &testcor)
{
	rnn.DisableDropout();

	double dloss = 0;
	unsigned dtokens = 0;
	unsigned id = 0;
	unsigned unk_dtokens = 0;
	for (auto& sent: testcor)
	{
		ComputationGraph cg;
		unsigned tokens = 0, unk_tokens = 0;
		Expression i_xent = rnn.BuildLMGraph(sent, tokens, unk_tokens, cg);

		//more score details for each sentence
		double loss = as_scalar(cg.forward(i_xent));
		//int tokens = sent.size() - 1;
		cerr << id++ << "\t" << loss << "\t" << tokens << "\t" << exp(loss / tokens) << endl;

		dloss += loss;
		dtokens += tokens;
		unk_dtokens += unk_tokens;
	}

	cerr << "-------------------------------------------------------------------------" << endl;
	cerr << "***TEST " << "sentences=" << testcor.size() << " unks=" << unk_dtokens << " E=" << (dloss / dtokens) << " ppl=" << exp(dloss / dtokens) << ' ';
	cerr << "\n-------------------------------------------------------------------------\n" << endl;
}

template <class RNNLM_t>
void TrainModel(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd_trainer
	, const string& param_file, float dropout_p)
{
	unsigned report_every_i = TREPORT;
	unsigned devcor_every_i_reports = DREPORT;
	double best = 9e+99;

	vector<unsigned> order((traincor.size() + BATCH_SIZE - 1) / BATCH_SIZE);
	for (unsigned i = 0; i < order.size(); ++i) order[i] = i * BATCH_SIZE;

	cerr << "**SHUFFLE\n";
	shuffle(order.begin(), order.end(), *rndeng);

	unsigned si = 0;//order.size();
	Timer timer_epoch("completed in"), timer_iteration("completed in");

	int report = 0;
	unsigned lines = 0;
	while (sgd_trainer->epoch < MAX_EPOCH) {
		rnn.EnableDropout(dropout_p);

		double loss = 0;
		unsigned tokens = 0, unk_tokens = 0;
		for (unsigned i = 0; i < report_every_i; ++i, ++si) {
			if (si == order.size()) {
				//timing
				cerr << "***Epoch " << sgd_trainer->epoch << " is finished. ";
				timer_epoch.show();

				si = 0;

				if (ETA_EPOCH == 0)
					sgd_trainer->update_epoch();
				else sgd_trainer->update_epoch(1, ETA_EPOCH); // @vhoang2: learning rate annealing (after lr_epochs, for every next epoch, the learning rate will be decreased by a factor of eta_decay.

				if (sgd_trainer->epoch >= MAX_EPOCH) break;

				cerr << "**SHUFFLE\n";
				shuffle(order.begin(), order.end(), *rndeng);

				timer_epoch.reset();
			}

			// build graph for this instance
			ComputationGraph cg;
			unsigned c1 = 0, c2 = 0;
			Expression i_xent = rnn.BuildLMGraph(traincor[order[si]], c1/*tokens*/, c2/*unk_tokens*/, cg);

			float closs = as_scalar(cg.forward(i_xent));// consume the loss
			if (!is_valid(closs)){
				std::cerr << "***Warning***: nan or -nan values occurred!" << std::endl;
				continue;
			}

			loss += closs;
			tokens += c1;
			unk_tokens += c2;

			cg.backward(i_xent);
			sgd_trainer->update();

			lines++;
		}

		if (sgd_trainer->epoch >= MAX_EPOCH) continue;

		sgd_trainer->status();
		cerr << "sents=" << lines << " unks=" << unk_tokens << " E=" << (loss / tokens) << " ppl=" << exp(loss / tokens) << ' ';
		double elapsed = timer_iteration.elapsed();
		cerr << "[time_elapsed=" << elapsed << "(msec)" << " (" << tokens * 1000.f / elapsed << " words/sec)]" << endl;
		timer_iteration.reset();

		//rnn.RandomSample(); // uncomment this to see some randomly-generated sentences

		// show score on devcor data?
		//report++;
		report += report_every_i;
		if (report % devcor_every_i_reports == 0) {
			rnn.DisableDropout();

			double dloss = 0;
			unsigned dtokens = 0, unk_dtokens = 0;
			for (auto& sent: devcor){
				ComputationGraph cg;
				Expression i_xent = rnn.BuildLMGraph(sent, dtokens, unk_dtokens, cg);
				dloss += as_scalar(cg.forward(i_xent));
			}

			if (dloss < best) {
				best = dloss;
				//ofstream out(param_file);
				//boost::archive::text_oarchive oa(out);
				//oa << lm;
				rnn.SaveModel(param_file);
			}
			//else
			//	sgd_trainer->eta *= 0.5;

			cerr << "\n***DEV [epoch=" << (lines / (double)traincor.size()) << " eta=" << sgd_trainer->eta << "]" << " sents=" << devcor.size() << " unks=" << unk_dtokens << " E=" << (dloss / dtokens) << " ppl=" << exp(dloss / dtokens) << ' ';
			timer_iteration.show();
			timer_iteration.reset();
		}
	}

	cerr << endl << "Training completed!" << endl;
}

//Note: This version works increasingly worse when batch_size > 16.
template <class RNNLM_t>
void TrainModel_Batch1(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd_trainer
	, const string& param_file, float dropout_p)
{
	if (BATCH_SIZE == 1){
		TrainModel(model, rnn, traincor, devcor, sgd_trainer, param_file, dropout_p);
		return;
	}

	// Sort the traincor sentences in descending order of length
	CompareLen comp;
	sort(traincor.begin(), traincor.end(), comp);
	// Pad the sentences in the same batch with EOS so they are the same length
	// This modifies the traincor objective a bit by making it necessary to
	// predict EOS multiple times, but it's easy and not so harmful
	// Potential risk: if there is a very long sentence, computation will be significantly increased!
	for(size_t i = 0; i < traincor.size(); i += BATCH_SIZE)
		for(size_t j = 1; j < BATCH_SIZE; ++j)
			while(traincor[i+j].size() < traincor[i].size())
				traincor[i+j].push_back(kEOS);

	unsigned report_every_i = TREPORT;
	unsigned devcor_every_i_reports = DREPORT;
	double best = 9e+99;

	vector<unsigned> order((traincor.size() + BATCH_SIZE - 1) / BATCH_SIZE);
	for (unsigned i = 0; i < order.size(); ++i) order[i] = i * BATCH_SIZE;

	cerr << "**SHUFFLE\n";
	shuffle(order.begin(), order.end(), *rndeng);

	unsigned si = 0;//order.size();
	Timer timer_epoch("completed in"), timer_iteration("completed in");

	int report = 0;
	unsigned lines = 0;
	while (sgd_trainer->epoch < MAX_EPOCH) {
		rnn.EnableDropout(dropout_p);

		double loss = 0;
		unsigned tokens = 0, unk_tokens = 0;
		for (unsigned i = 0; i < report_every_i; /*++i,*/ ++si) {
			if (si == order.size()) {
				//timing
				cerr << "***Epoch " << sgd_trainer->epoch << " is finished. ";
				timer_epoch.show();

				si = 0;

				if (ETA_EPOCH == 0)
					sgd_trainer->update_epoch();
				else sgd_trainer->update_epoch(1, ETA_EPOCH); // @vhoang2: learning rate annealing (after lr_epochs, for every next epoch, the learning rate will be decreased by a factor of eta_decay.

				if (sgd_trainer->epoch >= MAX_EPOCH) break;

				cerr << "**SHUFFLE\n";
				shuffle(order.begin(), order.end(), *rndeng);

				timer_epoch.reset();
			}

			// build graph for this instance
			ComputationGraph cg;
			unsigned bsize = std::min((unsigned)traincor.size()-order[si], BATCH_SIZE); // batch size
			unsigned c1 = 0, c2 = 0;
			Expression i_xent = rnn.BuildLMGraph(traincor, order[si], bsize, c1/*tokens*/, c2/*unk_tokens*/, cg);

			float closs = as_scalar(cg.forward(i_xent));// consume the loss
			if (!is_valid(closs)){
				std::cerr << "***Warning***: nan or -nan values occurred!" << std::endl;
				continue;
			}

			loss += closs;
			tokens += c1;
			unk_tokens += c2;

			cg.backward(i_xent);
			sgd_trainer->update();

			lines += bsize;
			i += bsize;
		}

		if (sgd_trainer->epoch >= MAX_EPOCH) continue;

		sgd_trainer->status();
		cerr << "sents=" << lines << " unks=" << unk_tokens << " E=" << (loss / tokens) << " ppl=" << exp(loss / tokens) << ' ';
		double elapsed = timer_iteration.elapsed();
		cerr << "[time_elapsed=" << elapsed << "(msec)" << " (" << tokens * 1000.f / elapsed << " words/sec)]" << endl;
		timer_iteration.reset();

		//rnn.RandomSample(); // uncomment this to see some randomly-generated sentences

		// show score on devcor data?
		//report++;
		report += report_every_i;
		if (report % devcor_every_i_reports == 0) {
			rnn.DisableDropout();

			double dloss = 0;
			unsigned dtokens = 0, unk_dtokens = 0;
			for (auto& sent: devcor){
				ComputationGraph cg;
				Expression i_xent = rnn.BuildLMGraph(sent, dtokens, unk_dtokens, cg);
				dloss += as_scalar(cg.forward(i_xent));
			}

			if (dloss < best) {
				best = dloss;
				//ofstream out(param_file);
				//boost::archive::text_oarchive oa(out);
				//oa << lm;
				rnn.SaveModel(param_file);
			}
			//else
			//	sgd_trainer->eta *= 0.5;

			cerr << "\n***DEV [epoch=" << (lines / (double)traincor.size()) << " eta=" << sgd_trainer->eta << "]" << " sents=" << devcor.size() << " unks=" << unk_dtokens << " E=" << (dloss / dtokens) << " ppl=" << exp(dloss / dtokens) << ' ';
			timer_iteration.show();
			timer_iteration.reset();
		}
	}

	cerr << endl << "Training completed!" << endl;
}

// --------------------------------------------------------------------------------------------------------------------------------
// The following codes are referenced from lamtram toolkit (https://github.com/neubig/lamtram).
struct SingleLength
{
	SingleLength(const vector<Sentence> & v) : vec(v) { }
	inline bool operator() (int i1, int i2)
	{
		return (vec[i2].size() < vec[i1].size());
	}
	const vector<Sentence> & vec;
};

inline size_t CalcSize(const Sentence & src, int trg) {
	return src.size()+1;
}

inline void Create_MiniBatches(const Corpus& traincor,
	size_t max_size,
	std::vector<std::vector<Sentence> > & traincor_minibatch)
{
	std::vector<int> train_ids(traincor.size());
	std::iota(train_ids.begin(), train_ids.end(), 0);

	if(max_size > 1)
		sort(train_ids.begin(), train_ids.end(), SingleLength(traincor));

	std::vector<Sentence> traincor_next;
	size_t first_size = 0;
	for(size_t i = 0; i < train_ids.size(); i++) {
		if (traincor_next.size() == 0)
			first_size = traincor[train_ids[i]].size();

		traincor_next.push_back(traincor[train_ids[i]]);

		if ((traincor_next.size()+1) * first_size > max_size) {
			traincor_minibatch.push_back(traincor_next);
			traincor_next.clear();
		}
	}

	if (traincor_next.size()) traincor_minibatch.push_back(traincor_next);
}
// --------------------------------------------------------------------------------------------------------------------------------

template <class RNNLM_t>
void TrainModel_Batch2(Model &model, RNNLM_t &rnn
	, Corpus &traincor, Corpus &devcor
	, Trainer* sgd_trainer
	, const string& param_file, float dropout_p)
{
	if (BATCH_SIZE == 1){
		TrainModel(model, rnn, traincor, devcor, sgd_trainer, param_file, dropout_p);
		return;
	}

	// create minibatches
	std::vector<std::vector<Sentence> > train_minibatch;
	size_t minibatch_size = BATCH_SIZE;
	Create_MiniBatches(traincor, minibatch_size, train_minibatch);

	std::vector<int> train_ids_minibatch(train_minibatch.size());
	std::iota(train_ids_minibatch.begin(), train_ids_minibatch.end(), 0);
	cerr << "**SHUFFLE\n";
	std::shuffle(train_ids_minibatch.begin(), train_ids_minibatch.end(), *dynet::rndeng);

	unsigned report_every_i = TREPORT;
	unsigned dev_every_i_reports = DREPORT;
	double best = 9e+99;
	unsigned si = 0, last_print = 0, lines = 0;
	Timer timer_epoch("completed in"), timer_iteration("completed in");
	while (sgd_trainer->epoch < MAX_EPOCH) {
		rnn.EnableDropout(dropout_p);

		double loss = 0;
		unsigned tokens = 0, unk_tokens = 0;
		for (unsigned i = 0; i < dev_every_i_reports; ++si) {
			if (si == train_ids_minibatch.size()) {
				//timing
				cerr << "***Epoch " << sgd_trainer->epoch << " is finished. ";
				timer_epoch.show();

				si = 0;
				last_print = 0;
				lines = 0;

				if (ETA_EPOCH == 0)
					sgd_trainer->update_epoch();
				else sgd_trainer->update_epoch(1, ETA_EPOCH); // @vhoang2: learning rate annealing (after lr_epochs, for every next epoch, the learning rate will be decreased by a factor of eta_decay.

				if (sgd_trainer->epoch >= MAX_EPOCH) break;

				cerr << "**SHUFFLE\n";
				shuffle(train_ids_minibatch.begin(), train_ids_minibatch.end(), *dynet::rndeng);

				timer_epoch.reset();
			}

			// build graph for this instance
			ComputationGraph cg;
			unsigned c1 = 0, c2 = 0;// intermediate variables
			Expression i_xent = rnn.BuildLMGraph(train_minibatch[train_ids_minibatch[si]], c1/*tokens*/, c2/*unk_tokens*/, cg);

			cg.forward(i_xent);// forward step
			float closs = as_scalar(cg.get_value(i_xent.i));// consume the loss
			if (!is_valid(closs)){
				std::cerr << "***Warning***: nan or -nan values occurred!" << std::endl;
				continue;
			}

			// update returned values
			loss += closs;
			tokens += c1;
			unk_tokens += c2;

			cg.backward(i_xent);// backward step
			sgd_trainer->update();// SGD update step

			lines += train_minibatch[train_ids_minibatch[si]].size();
			i += train_minibatch[train_ids_minibatch[si]].size();

			if (lines / report_every_i != last_print
					|| i >= dev_every_i_reports /*|| sgd.epoch >= max_epochs*/
					|| si + 1 == train_ids_minibatch.size()){
				last_print = lines / report_every_i;

				sgd_trainer->status();
				cerr << "sents=" << lines << " unks=" << unk_tokens << " E=" << (loss / tokens) << " ppl=" << exp(loss / tokens) << ' ';
				double elapsed = timer_iteration.elapsed();
				cerr << "[time_elapsed=" << elapsed << "(msec)" << " (" << tokens * 1000.f / elapsed << " words/sec)]" << endl;
			}
		}

		timer_iteration.reset();

		if (sgd_trainer->epoch >= MAX_EPOCH) continue;

		//rnn.RandomSample(); // uncomment this to see some randomly-generated sentences

		// show score on devcor data?
		rnn.DisableDropout();

		double dloss = 0;
		unsigned dtokens = 0, unk_dtokens = 0;
		for (auto& sent: devcor){
			ComputationGraph cg;
			Expression i_xent = rnn.BuildLMGraph(sent, dtokens, unk_dtokens, cg);
			dloss += as_scalar(cg.forward(i_xent));
		}

		if (dloss < best) {
			best = dloss;
			//ofstream out(param_file);
			//boost::archive::text_oarchive oa(out);
			//oa << lm;
			rnn.SaveModel(param_file);
		}
		//else
		//	sgd_trainer->eta *= 0.5;

		cerr << "--------------------------------------------------------------------------------------------------------" << endl;
		cerr << "***DEV [epoch=" << sgd_trainer->epoch + lines / (double)traincor.size() << " eta=" << sgd_trainer->eta << "]" << " sents=" << devcor.size() << " unks=" << unk_dtokens << " E=" << (dloss / dtokens) << " ppl=" << exp(dloss / dtokens) << ' ';
		timer_iteration.show();
		cerr << "--------------------------------------------------------------------------------------------------------" << endl;
		timer_iteration.reset();
	}

	cerr << endl << "Training completed!" << endl;
}

Corpus Read_Corpus(const string &fp, bool dir)
{
	Corpus cor;

	std::ifstream f(fp);

	string line;
	int lc = 0, toks = 0;
	while (std::getline(f, line))
	{
		// parse the line which can be: source ||| target
		size_t pos_sep = line.find("|||");
		if (pos_sep != std::string::npos){
			if (dir)// source
				line = line.substr(0, pos_sep);
			else// target
				line = line.substr(pos_sep + 3);
		}

		boost::trim(line);

		Sentence source;
		source = read_sentence(line, d);
		cor.push_back(Sentence(source));

		toks += source.size();

		if ((source.front() != kSOS && source.back() != kEOS))
		{
			cerr << "Sentence in " << fp << ":" << lc << " didn't start or end with <s> and </s>\n";
			abort();
		}

		lc++;
	}

	cerr << lc << " lines, " << toks << " tokens, " << d.size() << " types\n";

	return cor;
}

max_stars_repo_name: duyvuleo/Mantidae

max_issues_repo_name: duyvuleo/Mantidae

max_forks_repo_name: duyvuleo/Mantidae


text:
#include <boost/program_options.hpp>
//#include <experimental/filesystem>
#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
#include <regex>
#include <cstdlib>
#include <armadillo>
#include "atomsciflow/parser/cif.h"
#include "atomsciflow/parser/xyz.h"
#include "atomsciflow/base/crystal.h"
#include "atomsciflow/parser/xyztraj.h"
#include "atomsciflow/utils.h"

// needs: libboost-dev, libboost-program-options-dev

namespace po = boost::program_options;

//namespace filesys = std::experimental::filesystem;  // --std=c++17 -lstdc++fs
namespace filesys = boost::filesystem;     // --std=c++11 -lboost_filesystem -lboost_system

// used to allow negative number parsed to boost cmd option
std::vector<po::option> ignore_numbers(std::vector<std::string>& args)
{
    // this function can help to alow negative number args but it probhibits positional args
    // however we do not need positional args. so it is ok.
    std::vector<po::option> result;
    int pos = 0;
    while(!args.empty()) {
        const auto& arg = args[0];
        double num;
        if(boost::conversion::try_lexical_convert(arg, num)) {
            result.push_back(po::option());
            po::option& opt = result.back();

            opt.position_key = pos++;
            opt.value.push_back(arg);
            opt.original_tokens.push_back(arg);

            args.erase(args.begin());
        } else {
            break;
        }
    }

    return result;
}

int main(int argc, char const* argv[]) {
    //

    po::options_description global("Global options");
    global.add_options()
        ("command", po::value<std::string>(), "command to execute")
        ("subargs", po::value<std::vector<std::string> >(), "Arguments for command")
        ("help, h", "print out help information");

    po::positional_options_description pos;
    pos.add("command", 1).add("subargs", -1);

    po::variables_map vm;

    po::parsed_options parsed = po::command_line_parser(argc, argv).
        options(global).
        positional(pos).
        allow_unregistered().
        run();

    po::store(parsed, vm);

    std::cout << "**********************************************************************" << std::endl;
    std::cout << "*                       skit-traj.x utils runnig                     *" << std::endl;
    std::cout << "**********************************************************************" << std::endl;

    if (0 == vm.count("command")) { // or by vm.empty()
        std::cout << "You didn't specify any subcommand!\n";
        std::exit(1);
    }
    std::string cmd = vm["command"].as<std::string>();

    if (cmd == "tidy") {
        //
        std::cout << "----------------------------------------------------------------------" << std::endl;
        std::cout << "sub commands -> tidy                                               " << std::endl;
        std::cout << "Run info:" << std::endl;

        // tidy command has the following options:
        po::options_description opt_tidy("tidy options");
        opt_tidy.add_options()
            ("input, i", po::value<std::string>()->required(), "input xyz trajectory file")
            ("output, o", po::value<std::string>()->required(), "output xyz trajectory file")
            ("cell", po::value<std::vector<double>>()->multitoken()->required(), "cell parameter");
        //opts.add_options()
        //    ("input, i", po::value<std::string>(&input), "input structure file")
        //    ("output, o", po::value<std::string>(&output), "output structure file");
        // collect all the unrecognized options from the first pass. this will include the
        // (positional) command name so we need to erase that
        std::vector<std::string> opts = po::collect_unrecognized(parsed.options, po::include_positional);
        opts.erase(opts.begin());
        //parse again...
        po::store(po::command_line_parser(opts).options(opt_tidy).style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise).extra_style_parser(&ignore_numbers).run(), vm);

        if (vm.count("help")) {
            std::cout << opt_tidy << std::endl;
            std::exit(1);
        }
        po::notify(vm);

        if (vm.count("input") && vm.count("output")) {
            std::vector<atomsciflow::Crystal> trajectory;
            //crystal.read_xyz_file(vm["input"].as<std::string>());
            //crystal.write_cif_file(vm["output"].as<std::string>());

            std::string input_file = vm["input"].as<std::string>();
            std::string output_file = vm["output"].as<std::string>();

            filesys::path in_path(input_file);
            filesys::path out_path(output_file);

            std::cout << "input: " << input_file << std::endl;
            std::cout << "output: " << output_file << std::endl;

            // read structure file
            std::cout << "in_path(extension)->" << in_path.extension().string() << std::endl;

            atomsciflow::read_xyztraj_file(trajectory, input_file, 0);

            std::cout << "num of images: " << trajectory.size() << std::endl;

            std::vector<std::vector<double>> cell;
            std::vector<double> arg_cell = vm["cell"].as<std::vector<double>>();
            std::vector<double> vec;
            vec.push_back(arg_cell[0]);
            vec.push_back(arg_cell[1]);
            vec.push_back(arg_cell[2]);
            cell.push_back(vec);
            vec.clear();
            vec.push_back(arg_cell[3]);
            vec.push_back(arg_cell[4]);
            vec.push_back(arg_cell[5]);
            cell.push_back(vec);
            vec.clear();
            vec.push_back(arg_cell[6]);
            vec.push_back(arg_cell[7]);
            vec.push_back(arg_cell[8]);
            cell.push_back(vec);
            vec.clear();

            std::cout << "cell processed" << std::endl;

            for (auto& image : trajectory) {
                image.cell = cell;
                set_frac_within_zero_and_one(&image);
            }
            std::cout << "tidied" << std::endl;
            // write structure file
            atomsciflow::write_xyztraj_file(trajectory, output_file, 0);
        }

        std::cout << "----------------------------------------------------------------------" << std::endl;
        std::cout << "sub command: tidy finished!!!                                      " << std::endl;
        std::cout << "----------------------------------------------------------------------" << std::endl;

    } else {
        std::cout << "The specified subcommand is not defined!\n";
    }

    //
    return 0;
}

max_stars_repo_name: DeqiTang/pymatflow

max_issues_repo_name: DeqiTang/pymatflow

max_forks_repo_name: DeqiTang/pymatflow


text:
//  Copyright (c) 2001-2011 Hartmut Kaiser
//  Copyright (c) 2001-2011 Joel de Guzman
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#if !defined(SPIRIT_KARMA_DETAIL_ATTRIBUTES_APR_18_2010_0453PM)
#define SPIRIT_KARMA_DETAIL_ATTRIBUTES_APR_18_2010_0453PM

#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/support/attributes.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
    template <typename Exposed, typename Transformed, typename Enable = void>
    struct transform_attribute
    {
        typedef Transformed type;
        static Transformed pre(Exposed& val)
        {
            return Transformed(traits::extract_from<Exposed>(val, unused));
        }
        // Karma only, no post() and no fail() required
    };

    template <typename Exposed, typename Transformed>
    struct transform_attribute<boost::optional<Exposed> const, Transformed
      , typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
    {
        typedef Transformed const& type;
        static Transformed const& pre(boost::optional<Exposed> const& val)
        {
            return boost::get<Transformed>(val);
        }
    };

    template <typename Attribute>
    struct transform_attribute<Attribute const, Attribute>
    {
        typedef Attribute const& type;
        static Attribute const& pre(Attribute const& val) { return val; }
        // Karma only, no post() and no fail() required
    };

    // reference types need special handling
    template <typename Exposed, typename Transformed>
    struct transform_attribute<Exposed&, Transformed>
      : transform_attribute<Exposed, Transformed>
    {};

    template <typename Exposed, typename Transformed>
    struct transform_attribute<Exposed const&, Transformed>
      : transform_attribute<Exposed const, Transformed>
    {};

    template <typename Attribute>
    struct transform_attribute<Attribute const&, Attribute>
      : transform_attribute<Attribute const, Attribute>
    {};

    // unused_type needs some special handling as well
    template <>
    struct transform_attribute<unused_type, unused_type>
    {
        typedef unused_type type;
        static unused_type pre(unused_type) { return unused; }
    };

    template <>
    struct transform_attribute<unused_type const, unused_type>
      : transform_attribute<unused_type, unused_type>
    {};

    template <typename Attribute>
    struct transform_attribute<unused_type, Attribute>
      : transform_attribute<unused_type, unused_type>
    {};

    template <typename Attribute>
    struct transform_attribute<unused_type const, Attribute>
      : transform_attribute<unused_type, unused_type>
    {};

    template <typename Attribute>
    struct transform_attribute<Attribute, unused_type>
      : transform_attribute<unused_type, unused_type>
    {};

    template <typename Attribute>
    struct transform_attribute<Attribute const, unused_type>
      : transform_attribute<unused_type, unused_type>
    {};
}}}

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
    template <typename Exposed, typename Transformed>
    struct transform_attribute<Exposed, Transformed, karma::domain>
      : karma::transform_attribute<Exposed, Transformed>
    {};
}}}

#endif

max_stars_repo_name: nlchao/ofxBoost

max_issues_repo_name: ksundberg/boost-svn

max_forks_repo_name: ksundberg/boost-svn