<commit_before>#include "Session.h"

#include <fstream>
#include <string>
#include <iomanip>

#include <SmurffCpp/Version.h>

#include <SmurffCpp/Utils/omp_util.h>
#include <SmurffCpp/Utils/Distribution.h>
#include <SmurffCpp/Utils/MatrixUtils.h>
#include <SmurffCpp/Utils/counters.h>
#include <SmurffCpp/Utils/Error.h>

#include <SmurffCpp/DataMatrices/DataCreator.h>
#include <SmurffCpp/Priors/PriorFactory.h>

#include <SmurffCpp/result.h>
#include <SmurffCpp/StatusItem.h>

using namespace smurff;

void Session::setRestoreFromRootPath(std::string rootPath)
{
   // open root file
   m_rootFile = std::make_shared<RootFile>(rootPath);

   //restore config
   m_rootFile->restoreConfig(m_config);

   m_config.validate();

   //base functionality
   setFromBase();
}

void Session::setRestoreFromConfig(const Config& cfg, std::string rootPath)
{
   cfg.validate();

   // assign config
   m_config = cfg;

   // open root file
   m_rootFile = std::make_shared<RootFile>(rootPath);

   //base functionality
   setFromBase();
}

void Session::setCreateFromConfig(const Config& cfg)
{
   cfg.validate();

   // assign config
   m_config = cfg;

   if (m_config.getSaveFreq() || m_config.getCheckpointFreq())
   {

       // create root file
       m_rootFile = std::make_shared<RootFile>(m_config.getSavePrefix(), m_config.getSaveExtension());

       //save config
       m_rootFile->saveConfig(m_config);

       //flush record about options.ini
       m_rootFile->flushLast();
   }

    //base functionality
    setFromBase();
}

void Session::setFromBase()
{
   std::shared_ptr<Session> this_session = shared_from_this();

   // initialize pred

   if (m_config.getClassify())
      m_pred->setThreshold(m_config.getThreshold());

   if (m_config.getTest())
      m_pred->set(m_config.getTest());

   // initialize data

   data_ptr = m_config.getTrain()->create(std::make_shared<DataCreator>(this_session));

   // initialize priors

   std::shared_ptr<IPriorFactory> priorFactory = this->create_prior_factory();
   for (std::size_t i = 0; i < m_config.getPriorTypes().size(); i++)
      this->addPrior(priorFactory->create_prior(this_session, i));
}

void Session::init()
{
   //init omp
   threads_init(m_config.getVerbose());

   //initialize random generator
   initRng();

   //initialize train matrix (centring and noise model)
   data().init();

   //initialize model (samples)
   model().init(m_config.getNumLatent(), data().dim(), m_config.getModelInitType());

   //initialize priors
   for(auto &p : m_priors)
      p->init();

   //write header to status file
   if (m_config.getCsvStatus().size())
   {
      auto f = std::ofstream(m_config.getCsvStatus(), std::ofstream::out);
      THROWERROR_ASSERT_MSG(f, "Could not open status csv file: " + m_config.getCsvStatus());
      f << StatusItem::getCsvHeader() << std::endl;
   }

   //write info to console
   if (m_config.getVerbose())
      info(std::cout, "");

   //restore session (model, priors)
   bool resume = restore(m_iter);

   //print session status to console
   if (m_config.getVerbose())
   {
      printStatus(std::cout, resume);
   }

   is_init = true;
}

void Session::run()
{
   init();
   while (step());
}

bool Session::step()
{
   THROWERROR_ASSERT_MSG(is_init, "Session::init() needs to be called before ::step()")

   // go to the next iteration
   m_iter++;

   bool isStep = m_iter < m_config.getBurnin() + m_config.getNSamples();

   if (isStep)
   {
      //init omp
      threads_enable(m_config.getVerbose());

      THROWERROR_ASSERT(is_init);

      auto starti = tick();
      BaseSession::step();
      auto endi = tick();

      //WARNING: update is an expensive operation because of sort (when calculating AUC)
      m_pred->update(m_model, m_iter < m_config.getBurnin());

      m_secs_per_iter = endi - starti;

      printStatus(std::cout);

      save(m_iter);

      threads_disable(m_config.getVerbose());
   }

   return isStep;
}

std::ostream& Session::info(std::ostream &os, std::string indent)
{
   os << indent << name << " {\n";

   BaseSession::info(os, indent);

   os << indent << "  Version: " << smurff::SMURFF_VERSION << "\n" ;
   os << indent << "  Iterations: " << m_config.getBurnin() << " burnin + " << m_config.getNSamples() << " samples\n";

   if (m_config.getSaveFreq() != 0 || m_config.getCheckpointFreq() != 0)
   {
      if (m_config.getSaveFreq() > 0)
      {
          os << indent << "  Save model: every " << m_config.getSaveFreq() << " iteration\n";
      }
      else if (m_config.getSaveFreq() < 0)
      {
          os << indent << "  Save model after last iteration\n";
      }

      if (m_config.getCheckpointFreq() > 0)
      {
          os << indent << "  Checkpoint state: every " << m_config.getCheckpointFreq() << " seconds\n";
      }

      os << indent << "  Save prefix: " << m_config.getSavePrefix() << "\n";
      os << indent << "  Save extension: " << m_config.getSaveExtension() << "\n";
   }
   else
   {
      os << indent << "  Save model: never\n";
   }

   os << indent << "}\n";
   return os;
}

void Session::save(int iteration)
{
   //do not save if 'never save' mode is selected
   if (!m_config.getSaveFreq() &&
       !m_config.getCheckpointFreq() &&
       !m_config.getCsvStatus().size())
      return;

   std::int32_t isample = iteration - m_config.getBurnin() + 1;

   //save if checkpoint threshold overdue
   if (m_config.getCheckpointFreq() && (tick() - m_lastCheckpointTime) >= m_config.getCheckpointFreq())
   {
      std::int32_t icheckpoint = iteration + 1;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createCheckpointStepFile(icheckpoint);
      saveInternal(stepFile);

      //remove previous iteration if required (initial m_lastCheckpointIter is -1 which means that it does not exist)
      if (m_lastCheckpointIter >= 0)
      {
         std::int32_t icheckpointPrev = m_lastCheckpointIter + 1;

         //remove previous iteration
         m_rootFile->removeCheckpointStepFile(icheckpointPrev);

         //flush last item in a root file
         m_rootFile->flushLast();
      }

      //upddate counters
      m_lastCheckpointTime = tick();
      m_lastCheckpointIter = iteration;
   }

   //save model during sampling stage
   if (m_config.getSaveFreq() && isample > 0)
   {
      //save_freq > 0: check modulo - do not save if not a save iteration
      if (m_config.getSaveFreq() > 0 && (isample % m_config.getSaveFreq()) != 0)
      {
          // don't save
      }
      //save_freq < 0: save last iter - do not save if (final model) mode is selected and not a final iteration
      else if (m_config.getSaveFreq() < 0 && isample < m_config.getNSamples())
      {
          // don't save
      }
      else
      {
          //do save this iteration
          std::shared_ptr<StepFile> stepFile = m_rootFile->createSampleStepFile(isample);
          saveInternal(stepFile);
      }
   }
}

void Session::saveInternal(std::shared_ptr<StepFile> stepFile)
{
   if (m_config.getVerbose())
   {
      std::cout << "-- Saving model, predictions,... into '" << stepFile->getStepFileName() << "'." << std::endl;
   }

   BaseSession::save(stepFile);

   //flush last item in a root file
   m_rootFile->flushLast();
}

bool Session::restore(int& iteration)
{
   std::shared_ptr<StepFile> stepFile = nullptr;
   if (m_rootFile)
   {
       stepFile = m_rootFile->openLastStepFile();
   }

   if (!stepFile)
   {
      //if there is nothing to restore - start from initial iteration
      iteration = -1;

      //to keep track at what time we last checkpointed
      m_lastCheckpointTime = tick();
      m_lastCheckpointIter = -1;
      return false;
   }
   else
   {
      if (m_config.getVerbose())
      {
         std::cout << "-- Restoring model, predictions,... from '" << stepFile->getStepFileName() << "'." << std::endl;
      }

      BaseSession::restore(stepFile);

      //restore last iteration index
      if (stepFile->getCheckpoint())
      {
         iteration = stepFile->getIsample() - 1; //restore original state

         //to keep track at what time we last checkpointed
         m_lastCheckpointTime = tick();
         m_lastCheckpointIter = iteration;
      }
      else
      {
         iteration = stepFile->getIsample() + m_config.getBurnin() - 1; //restore original state

         //to keep track at what time we last checkpointed
         m_lastCheckpointTime = tick();
         m_lastCheckpointIter = iteration;
      }

      return true;
   }
}

std::shared_ptr<StatusItem> Session::getStatus() const
{
    std::shared_ptr<StatusItem> ret = std::make_shared<StatusItem>();

    if (m_iter < 0)
    {
        ret->phase = "Initial";
        ret->iter = m_iter + 1;
        ret->phase_iter = 0;
    }
    else if (m_iter < m_config.getBurnin())
    {
        ret->phase = "Burnin";
        ret->iter = m_iter + 1;
        ret->phase_iter = m_config.getBurnin();
    }
    else
    {
        ret->phase = "Sample";
        ret->iter = m_iter - m_config.getBurnin() + 1;
        ret->phase_iter = m_config.getNSamples();
    }

    for (int i = 0; i < model().nmodes(); ++i)
    {
        ret->model_norms.push_back(model().U(i).norm());
    }

    ret->train_rmse = data().train_rmse(model());

    ret->rmse_avg = m_pred->rmse_avg;
    ret->rmse_1sample = m_pred->rmse_1sample;

    ret->auc_avg = m_pred->auc_avg;
    ret->auc_1sample = m_pred->auc_1sample;

    ret->elapsed_iter = m_secs_per_iter;
    ret->nnz_per_sec = (double)(data().nnz()) / m_secs_per_iter;
    ret->samples_per_sec = (double)(model().nsamples()) / m_secs_per_iter;

    return ret;
}

void Session::printStatus(std::ostream& output, bool resume)
{
   if(!m_config.getVerbose() &&
      !m_config.getCsvStatus().size())
      return;

   auto status_item = getStatus();

   std::string resumeString = resume ? "Continue from " : std::string();

   if (m_config.getVerbose() > 0)
   {
       if (m_iter < 0)
       {
           output << " ====== Initial phase ====== " << std::endl;
       }
       else if (m_iter < m_config.getBurnin() && m_iter == 0)
       {
           output << " ====== Sampling (burning phase) ====== " << std::endl;
       }
       else if (m_iter == m_config.getBurnin())
       {
           output << " ====== Burn-in complete, averaging samples ====== " << std::endl;
       }

       output << resumeString
           << status_item->phase
           << " "
           << std::setfill(' ') << std::setw(3) << status_item->iter
           << "/"
           << std::setfill(' ') << std::setw(3) << status_item->phase_iter
           << ": RMSE: "
           << std::fixed << std::setprecision(4) << status_item->rmse_avg
           << " (1samp: "
           << std::fixed << std::setprecision(4) << status_item->rmse_1sample
           << ")";

       if (m_config.getClassify())
       {
           output << " AUC:"
               << std::fixed << std::setprecision(4) << status_item->auc_avg
               << " (1samp: "
               << std::fixed << std::setprecision(4) << status_item->auc_1sample
               << ")"
               << std::endl;
       }

       output << "  U:[";
       for(double n: status_item->model_norms)
       {
           output << std::scientific << std::setprecision(2) << n << ", ";
       }
       output << "] [took: "
           << std::fixed << std::setprecision(1) << status_item->elapsed_iter
           << "s]"
           << std::endl;

       if (m_config.getVerbose() > 1)
       {
           output << std::fixed << std::setprecision(4) << "  RMSE train: " << status_item->train_rmse << std::endl;
           output << "  Priors:" << std::endl;

           for(const auto &p : m_priors)
               p->status(output, "     ");

           output << "  Model:" << std::endl;
           model().status(output, "    ");
           output << "  Noise:" << std::endl;
           data().status(output, "    ");
       }

       if (m_config.getVerbose() > 2)
       {
           output << "  Compute Performance: " << status_item->samples_per_sec << " samples/sec, " << status_item->nnz_per_sec << " nnz/sec" << std::endl;
       }
   }

   if (m_config.getCsvStatus().size())
   {
      auto f = std::ofstream(m_config.getCsvStatus(), std::ofstream::out | std::ofstream::app);
      THROWERROR_ASSERT_MSG(f, "Could not open status csv file: " + m_config.getCsvStatus());
      f << status_item->asCsvString() << std::endl;
   }
}

std::string StatusItem::getCsvHeader()
{
   return "phase;iter;phase_len;rmse_avg;rmse_1samp;train_rmse;auc_avg;auc_1samp;elapsed";
}

std::string StatusItem::asCsvString() const
{
    char ret[1024];
    snprintf(ret, 1024, "%s;%d;%d;%.4f;%.4f;%.4f;%.4f;:%.4f;%0.1f",
                  phase.c_str(), iter, phase_iter, rmse_avg, rmse_1sample, train_rmse,
                  auc_1sample, auc_avg, elapsed_iter);

    return ret;
}

void Session::initRng()
{
   //init random generator
   if (m_config.getRandomSeedSet())
      init_bmrng(m_config.getRandomSeed());
   else
      init_bmrng();
}

std::shared_ptr<IPriorFactory> Session::create_prior_factory() const
{
   return std::make_shared<PriorFactory>();
}
<commit_msg>Fix for deleted ofstream c'tor<commit_after>#include "Session.h"

#include <fstream>
#include <string>
#include <iomanip>

#include <SmurffCpp/Version.h>

#include <SmurffCpp/Utils/omp_util.h>
#include <SmurffCpp/Utils/Distribution.h>
#include <SmurffCpp/Utils/MatrixUtils.h>
#include <SmurffCpp/Utils/counters.h>
#include <SmurffCpp/Utils/Error.h>

#include <SmurffCpp/DataMatrices/DataCreator.h>
#include <SmurffCpp/Priors/PriorFactory.h>

#include <SmurffCpp/result.h>
#include <SmurffCpp/StatusItem.h>

using namespace smurff;

void Session::setRestoreFromRootPath(std::string rootPath)
{
   // open root file
   m_rootFile = std::make_shared<RootFile>(rootPath);

   //restore config
   m_rootFile->restoreConfig(m_config);

   m_config.validate();

   //base functionality
   setFromBase();
}

void Session::setRestoreFromConfig(const Config& cfg, std::string rootPath)
{
   cfg.validate();

   // assign config
   m_config = cfg;

   // open root file
   m_rootFile = std::make_shared<RootFile>(rootPath);

   //base functionality
   setFromBase();
}

void Session::setCreateFromConfig(const Config& cfg)
{
   cfg.validate();

   // assign config
   m_config = cfg;

   if (m_config.getSaveFreq() || m_config.getCheckpointFreq())
   {

       // create root file
       m_rootFile = std::make_shared<RootFile>(m_config.getSavePrefix(), m_config.getSaveExtension());

       //save config
       m_rootFile->saveConfig(m_config);

       //flush record about options.ini
       m_rootFile->flushLast();
   }

    //base functionality
    setFromBase();
}

void Session::setFromBase()
{
   std::shared_ptr<Session> this_session = shared_from_this();

   // initialize pred

   if (m_config.getClassify())
      m_pred->setThreshold(m_config.getThreshold());

   if (m_config.getTest())
      m_pred->set(m_config.getTest());

   // initialize data

   data_ptr = m_config.getTrain()->create(std::make_shared<DataCreator>(this_session));

   // initialize priors

   std::shared_ptr<IPriorFactory> priorFactory = this->create_prior_factory();
   for (std::size_t i = 0; i < m_config.getPriorTypes().size(); i++)
      this->addPrior(priorFactory->create_prior(this_session, i));
}

void Session::init()
{
   //init omp
   threads_init(m_config.getVerbose());

   //initialize random generator
   initRng();

   //initialize train matrix (centring and noise model)
   data().init();

   //initialize model (samples)
   model().init(m_config.getNumLatent(), data().dim(), m_config.getModelInitType());

   //initialize priors
   for(auto &p : m_priors)
      p->init();

   //write header to status file
   if (m_config.getCsvStatus().size())
   {
      std::ofstream f(m_config.getCsvStatus(), std::ofstream::out);
      THROWERROR_ASSERT_MSG(f, "Could not open status csv file: " + m_config.getCsvStatus());
      f << StatusItem::getCsvHeader() << std::endl;
   }

   //write info to console
   if (m_config.getVerbose())
      info(std::cout, "");

   //restore session (model, priors)
   bool resume = restore(m_iter);

   //print session status to console
   if (m_config.getVerbose())
   {
      printStatus(std::cout, resume);
   }

   is_init = true;
}

void Session::run()
{
   init();
   while (step());
}

bool Session::step()
{
   THROWERROR_ASSERT_MSG(is_init, "Session::init() needs to be called before ::step()")

   // go to the next iteration
   m_iter++;

   bool isStep = m_iter < m_config.getBurnin() + m_config.getNSamples();

   if (isStep)
   {
      //init omp
      threads_enable(m_config.getVerbose());

      THROWERROR_ASSERT(is_init);

      auto starti = tick();
      BaseSession::step();
      auto endi = tick();

      //WARNING: update is an expensive operation because of sort (when calculating AUC)
      m_pred->update(m_model, m_iter < m_config.getBurnin());

      m_secs_per_iter = endi - starti;

      printStatus(std::cout);

      save(m_iter);

      threads_disable(m_config.getVerbose());
   }

   return isStep;
}

std::ostream& Session::info(std::ostream &os, std::string indent)
{
   os << indent << name << " {\n";

   BaseSession::info(os, indent);

   os << indent << "  Version: " << smurff::SMURFF_VERSION << "\n" ;
   os << indent << "  Iterations: " << m_config.getBurnin() << " burnin + " << m_config.getNSamples() << " samples\n";

   if (m_config.getSaveFreq() != 0 || m_config.getCheckpointFreq() != 0)
   {
      if (m_config.getSaveFreq() > 0)
      {
          os << indent << "  Save model: every " << m_config.getSaveFreq() << " iteration\n";
      }
      else if (m_config.getSaveFreq() < 0)
      {
          os << indent << "  Save model after last iteration\n";
      }

      if (m_config.getCheckpointFreq() > 0)
      {
          os << indent << "  Checkpoint state: every " << m_config.getCheckpointFreq() << " seconds\n";
      }

      os << indent << "  Save prefix: " << m_config.getSavePrefix() << "\n";
      os << indent << "  Save extension: " << m_config.getSaveExtension() << "\n";
   }
   else
   {
      os << indent << "  Save model: never\n";
   }

   os << indent << "}\n";
   return os;
}

void Session::save(int iteration)
{
   //do not save if 'never save' mode is selected
   if (!m_config.getSaveFreq() &&
       !m_config.getCheckpointFreq() &&
       !m_config.getCsvStatus().size())
      return;

   std::int32_t isample = iteration - m_config.getBurnin() + 1;

   //save if checkpoint threshold overdue
   if (m_config.getCheckpointFreq() && (tick() - m_lastCheckpointTime) >= m_config.getCheckpointFreq())
   {
      std::int32_t icheckpoint = iteration + 1;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createCheckpointStepFile(icheckpoint);
      saveInternal(stepFile);

      //remove previous iteration if required (initial m_lastCheckpointIter is -1 which means that it does not exist)
      if (m_lastCheckpointIter >= 0)
      {
         std::int32_t icheckpointPrev = m_lastCheckpointIter + 1;

         //remove previous iteration
         m_rootFile->removeCheckpointStepFile(icheckpointPrev);

         //flush last item in a root file
         m_rootFile->flushLast();
      }

      //upddate counters
      m_lastCheckpointTime = tick();
      m_lastCheckpointIter = iteration;
   }

   //save model during sampling stage
   if (m_config.getSaveFreq() && isample > 0)
   {
      //save_freq > 0: check modulo - do not save if not a save iteration
      if (m_config.getSaveFreq() > 0 && (isample % m_config.getSaveFreq()) != 0)
      {
          // don't save
      }
      //save_freq < 0: save last iter - do not save if (final model) mode is selected and not a final iteration
      else if (m_config.getSaveFreq() < 0 && isample < m_config.getNSamples())
      {
          // don't save
      }
      else
      {
          //do save this iteration
          std::shared_ptr<StepFile> stepFile = m_rootFile->createSampleStepFile(isample);
          saveInternal(stepFile);
      }
   }
}

void Session::saveInternal(std::shared_ptr<StepFile> stepFile)
{
   if (m_config.getVerbose())
   {
      std::cout << "-- Saving model, predictions,... into '" << stepFile->getStepFileName() << "'." << std::endl;
   }

   BaseSession::save(stepFile);

   //flush last item in a root file
   m_rootFile->flushLast();
}

bool Session::restore(int& iteration)
{
   std::shared_ptr<StepFile> stepFile = nullptr;
   if (m_rootFile)
   {
       stepFile = m_rootFile->openLastStepFile();
   }

   if (!stepFile)
   {
      //if there is nothing to restore - start from initial iteration
      iteration = -1;

      //to keep track at what time we last checkpointed
      m_lastCheckpointTime = tick();
      m_lastCheckpointIter = -1;
      return false;
   }
   else
   {
      if (m_config.getVerbose())
      {
         std::cout << "-- Restoring model, predictions,... from '" << stepFile->getStepFileName() << "'." << std::endl;
      }

      BaseSession::restore(stepFile);

      //restore last iteration index
      if (stepFile->getCheckpoint())
      {
         iteration = stepFile->getIsample() - 1; //restore original state

         //to keep track at what time we last checkpointed
         m_lastCheckpointTime = tick();
         m_lastCheckpointIter = iteration;
      }
      else
      {
         iteration = stepFile->getIsample() + m_config.getBurnin() - 1; //restore original state

         //to keep track at what time we last checkpointed
         m_lastCheckpointTime = tick();
         m_lastCheckpointIter = iteration;
      }

      return true;
   }
}

std::shared_ptr<StatusItem> Session::getStatus() const
{
    std::shared_ptr<StatusItem> ret = std::make_shared<StatusItem>();

    if (m_iter < 0)
    {
        ret->phase = "Initial";
        ret->iter = m_iter + 1;
        ret->phase_iter = 0;
    }
    else if (m_iter < m_config.getBurnin())
    {
        ret->phase = "Burnin";
        ret->iter = m_iter + 1;
        ret->phase_iter = m_config.getBurnin();
    }
    else
    {
        ret->phase = "Sample";
        ret->iter = m_iter - m_config.getBurnin() + 1;
        ret->phase_iter = m_config.getNSamples();
    }

    for (int i = 0; i < model().nmodes(); ++i)
    {
        ret->model_norms.push_back(model().U(i).norm());
    }

    ret->train_rmse = data().train_rmse(model());

    ret->rmse_avg = m_pred->rmse_avg;
    ret->rmse_1sample = m_pred->rmse_1sample;

    ret->auc_avg = m_pred->auc_avg;
    ret->auc_1sample = m_pred->auc_1sample;

    ret->elapsed_iter = m_secs_per_iter;
    ret->nnz_per_sec = (double)(data().nnz()) / m_secs_per_iter;
    ret->samples_per_sec = (double)(model().nsamples()) / m_secs_per_iter;

    return ret;
}

void Session::printStatus(std::ostream& output, bool resume)
{
   if(!m_config.getVerbose() &&
      !m_config.getCsvStatus().size())
      return;

   auto status_item = getStatus();

   std::string resumeString = resume ? "Continue from " : std::string();

   if (m_config.getVerbose() > 0)
   {
       if (m_iter < 0)
       {
           output << " ====== Initial phase ====== " << std::endl;
       }
       else if (m_iter < m_config.getBurnin() && m_iter == 0)
       {
           output << " ====== Sampling (burning phase) ====== " << std::endl;
       }
       else if (m_iter == m_config.getBurnin())
       {
           output << " ====== Burn-in complete, averaging samples ====== " << std::endl;
       }

       output << resumeString
           << status_item->phase
           << " "
           << std::setfill(' ') << std::setw(3) << status_item->iter
           << "/"
           << std::setfill(' ') << std::setw(3) << status_item->phase_iter
           << ": RMSE: "
           << std::fixed << std::setprecision(4) << status_item->rmse_avg
           << " (1samp: "
           << std::fixed << std::setprecision(4) << status_item->rmse_1sample
           << ")";

       if (m_config.getClassify())
       {
           output << " AUC:"
               << std::fixed << std::setprecision(4) << status_item->auc_avg
               << " (1samp: "
               << std::fixed << std::setprecision(4) << status_item->auc_1sample
               << ")"
               << std::endl;
       }

       output << "  U:[";
       for(double n: status_item->model_norms)
       {
           output << std::scientific << std::setprecision(2) << n << ", ";
       }
       output << "] [took: "
           << std::fixed << std::setprecision(1) << status_item->elapsed_iter
           << "s]"
           << std::endl;

       if (m_config.getVerbose() > 1)
       {
           output << std::fixed << std::setprecision(4) << "  RMSE train: " << status_item->train_rmse << std::endl;
           output << "  Priors:" << std::endl;

           for(const auto &p : m_priors)
               p->status(output, "     ");

           output << "  Model:" << std::endl;
           model().status(output, "    ");
           output << "  Noise:" << std::endl;
           data().status(output, "    ");
       }

       if (m_config.getVerbose() > 2)
       {
           output << "  Compute Performance: " << status_item->samples_per_sec << " samples/sec, " << status_item->nnz_per_sec << " nnz/sec" << std::endl;
       }
   }

   if (m_config.getCsvStatus().size())
   {
      std::ofstream f(m_config.getCsvStatus(), std::ofstream::out | std::ofstream::app);
      THROWERROR_ASSERT_MSG(f, "Could not open status csv file: " + m_config.getCsvStatus());
      f << status_item->asCsvString() << std::endl;
   }
}

std::string StatusItem::getCsvHeader()
{
   return "phase;iter;phase_len;rmse_avg;rmse_1samp;train_rmse;auc_avg;auc_1samp;elapsed";
}

std::string StatusItem::asCsvString() const
{
    char ret[1024];
    snprintf(ret, 1024, "%s;%d;%d;%.4f;%.4f;%.4f;%.4f;:%.4f;%0.1f",
                  phase.c_str(), iter, phase_iter, rmse_avg, rmse_1sample, train_rmse,
                  auc_1sample, auc_avg, elapsed_iter);

    return ret;
}

void Session::initRng()
{
   //init random generator
   if (m_config.getRandomSeedSet())
      init_bmrng(m_config.getRandomSeed());
   else
      init_bmrng();
}

std::shared_ptr<IPriorFactory> Session::create_prior_factory() const
{
   return std::make_shared<PriorFactory>();
}
<|endoftext|>


<commit_before>#include "EditorInputHandler.h"

EditorInputHandler::EditorInputHandler(HINSTANCE handleInstance, HWND handle, Camera* camera, int w, int h)
{
	this->m_Width = w;
	this->m_Height = h;
	HRESULT hr = DirectInput8Create(
		handleInstance,
		DIRECTINPUT_VERSION,
		IID_IDirectInput8,
		(void**)&m_directInput,
		NULL);

	hr = m_directInput->CreateDevice(GUID_SysKeyboard,
		&DIKeyboard,
		NULL);

	hr = m_directInput->CreateDevice(GUID_SysMouse,
		&DIMouse,
		NULL);

	hr = DIKeyboard->SetDataFormat(&c_dfDIKeyboard);
	hr = DIKeyboard->SetCooperativeLevel(handle, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

	hr = DIMouse->SetDataFormat(&c_dfDIMouse);
	hr = DIMouse->SetCooperativeLevel(handle, DISCL_EXCLUSIVE | DISCL_NOWINKEY | DISCL_FOREGROUND);
	this->m_hwnd = handle;
	this->m_Camera = camera;
	this->m_PreviousPos = camera->GetCameraPos();
}

EditorInputHandler::~EditorInputHandler()
{
}

void EditorInputHandler::detectInput(double dT)
{

	DIMOUSESTATE mouseCurrentState;

	BYTE keyBoardState[256]; // the amount of buttons a char array of 256.

	DIKeyboard->Acquire();
	DIMouse->Acquire();

	DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrentState);

	DIKeyboard->GetDeviceState(sizeof(keyBoardState), (LPVOID)&keyBoardState);

	float speed = 10.0f * dT;
	float speedrot = 5.0f * dT;
	int result = 1;
	float translateCameraX = 0, translateCameraY = 0, translateCameraZ = 0;
	float yaw = 0, pitch = 0;

	POINT mousePos;
	GetCursorPos(&mousePos);
	ScreenToClient(this->m_hwnd, &mousePos);

#pragma region SHIFT + ALT +

#pragma endregion
#pragma region CONTROL +
	if (keyBoardState[DIK_LCONTROL] & 0x80)
	{
		if (mouseCurrentState.rgbButtons[0])
		{
			DirectX::XMVECTOR rayOrigin, rayDirection;
			int m_MouseX = mousePos.x;
			int m_MouseY = mousePos.y;
			if (m_MouseX > m_Width)
				m_MouseX = m_Width;
			else if (m_MouseX < 0)
				m_MouseX = 0;
			if (m_MouseY > m_Height)
				m_MouseY = m_Height;
			else if (m_MouseY < 0)
				m_MouseY = 0;

			DirectX::XMVECTOR localRayDirection = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
			DirectX::XMVECTOR LocalRayOrigin = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
			float X, Y, Z;
			DirectX::XMFLOAT4X4 camProjection;
			float fieldOfView = (float)DirectX::XM_PI / 4.0f;
			float screenAspect = (float)m_Width / (float)m_Height;

			DirectX::XMStoreFloat4x4(
				&camProjection,
				DirectX::XMMatrixPerspectiveFovLH(
					fieldOfView,
					screenAspect,
					0.1f,
					1000.0f)
			);

			//Transform 2D pick position on screen space to 3D ray in View space
			X = (((2.0f * m_MouseX) / m_Width) - 1) / camProjection._11;
			Y = -(((2.0f * m_MouseY) / m_Height) - 1) / camProjection._22;
			Z = 1.0f;    //View space's Z direction ranges from 0 to 1, so we set 1 since the ray goes "into" the screen

			localRayDirection = DirectX::XMVectorSet(X, Y, Z, 0.0f);

			DirectX::XMMATRIX inverseCamView;
			DirectX::XMVECTOR det = { 1,1,1,1 };
			DirectX::XMMATRIX temp;
			this->m_Camera->GetBaseViewMatrix(temp);

			//inverseCamView = DirectX::XMMatrixInverse(&det, temp);

			//rayOrigin = XMVector3TransformCoord(LocalRayOrigin, inverseCamView);
			//rayDirection = DirectX::XMVector3TransformNormal(localRayDirection, inverseCamView);
			//rayDirection = DirectX::XMVector3Normalize(rayDirection);

			DirectX::XMFLOAT4 test;
			DirectX::XMStoreFloat4(&test, localRayDirection);
			this->m_Camera->SetLookAt(test);
		}
	}
#pragma endregion
#pragma region SHIFT +
	if (keyBoardState[DIK_LSHIFT] & 0x80)
	{
		if (keyBoardState[DIK_W] & 0x80)
		{
			translateCameraZ += speed;
		}
		if (keyBoardState[DIK_S] & 0x80)
		{
			translateCameraZ -= speed;
		}
		if (keyBoardState[DIK_A] & 0x80)
		{
			translateCameraX += speed;
		}
		if (keyBoardState[DIK_D] & 0x80)
		{
			translateCameraX -= speed;
		}
		if (keyBoardState[DIK_C] & 0x80)
		{
			translateCameraY -= speed;
		}
		if (keyBoardState[DIK_SPACE] & 0x80)
		{
			translateCameraY += speed;
		}
		if (mouseCurrentState.rgbButtons[0])
		{
			if (mouseCurrentState.lY < 0)
			{
				translateCameraZ += speedrot;
			}
			if (mouseCurrentState.lY > 0)
			{
				translateCameraZ -= speedrot;
			}

		}

	}
#pragma endregion
	if (keyBoardState[DIK_LALT] & 0x80)
	{
		if (mouseCurrentState.rgbButtons[0])
		{
			if ((mouseCurrentState.lX!= m_mouseLastState.lX) || (mouseCurrentState.lY != m_mouseLastState.lY))
			{
				pitch += mouseCurrentState.lX * 0.01f;

				yaw += mouseCurrentState.lY * 0.01f;

				// Ensure the mouse location doesn't exceed the screen width or height.
				if (m_MouseX < 0) { m_MouseX = 0; }
				if (m_MouseY < 0) { m_MouseY = 0; }

				if (m_MouseX > m_Width) { m_MouseX = m_Width; }
				if (m_MouseY > m_Height) { m_MouseY = m_Height; }

				m_mouseLastState = mouseCurrentState;
			}
		}
	}

	if ((translateCameraY || translateCameraZ || translateCameraX))
	{
		DirectX::XMFLOAT3 posTranslation =
			DirectX::XMFLOAT3(
				float(translateCameraX),
				float(translateCameraY),
				float(translateCameraZ)
			);

		this->m_PreviousPos = this->m_Camera->GetCameraPos();
		this->m_Camera->ApplyLocalTranslation(
			float(translateCameraZ),
			float(translateCameraY),
			float(translateCameraX)
		);
		//this->m_Camera->AddToCameraPos(posTranslation);
		//this->m_Camera->AddToLookAt(posTranslation);
		this->m_Camera->Update();
	}

		float rotationAmount = DirectX::XM_PI / 8;

		DirectX::XMFLOAT4 newRotation =
			DirectX::XMFLOAT4(
				yaw * DirectX::XMScalarSin(rotationAmount / 2.0f),
				pitch * DirectX::XMScalarSin(rotationAmount / 2.0f),
				0.0f,
				DirectX::XMScalarCos(rotationAmount / 2.0f)
			);

		this->m_Camera->SetRotation(newRotation);
		//this->m_Camera->ApplyRotation(newRotation);
		this->m_Camera->Update();
	this->m_Camera->Update();
}
<commit_msg>UPDATE applied fix from camera branch<commit_after>#include "EditorInputHandler.h"

EditorInputHandler::EditorInputHandler(HINSTANCE handleInstance, HWND handle, Camera* camera, int w, int h)
{
	this->m_Width = w;
	this->m_Height = h;
	HRESULT hr = DirectInput8Create(
		handleInstance,
		DIRECTINPUT_VERSION,
		IID_IDirectInput8,
		(void**)&m_directInput,
		NULL);

	hr = m_directInput->CreateDevice(GUID_SysKeyboard,
		&DIKeyboard,
		NULL);

	hr = m_directInput->CreateDevice(GUID_SysMouse,
		&DIMouse,
		NULL);

	hr = DIKeyboard->SetDataFormat(&c_dfDIKeyboard);
	hr = DIKeyboard->SetCooperativeLevel(handle, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

	hr = DIMouse->SetDataFormat(&c_dfDIMouse);
	hr = DIMouse->SetCooperativeLevel(handle, DISCL_EXCLUSIVE | DISCL_NOWINKEY | DISCL_FOREGROUND);
	this->m_hwnd = handle;
	this->m_Camera = camera;
	this->m_PreviousPos = camera->GetCameraPos();
}

EditorInputHandler::~EditorInputHandler()
{
}

void EditorInputHandler::detectInput(double dT)
{

	DIMOUSESTATE mouseCurrentState;

	BYTE keyBoardState[256]; // the amount of buttons a char array of 256.

	DIKeyboard->Acquire();
	DIMouse->Acquire();

	DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrentState);

	DIKeyboard->GetDeviceState(sizeof(keyBoardState), (LPVOID)&keyBoardState);

	float speed = 10.0f * dT;
	float speedrot = 5.0f * dT;
	int result = 1;
	float translateCameraX = 0, translateCameraY = 0, translateCameraZ = 0;
	float yaw = 0, pitch = 0;

	POINT mousePos;
	GetCursorPos(&mousePos);
	ScreenToClient(this->m_hwnd, &mousePos);

#pragma region SHIFT + ALT +

#pragma endregion
#pragma region CONTROL +
	if (keyBoardState[DIK_LCONTROL] & 0x80)
	{
		if (mouseCurrentState.rgbButtons[0])
		{
			DirectX::XMVECTOR rayOrigin, rayDirection;
			int m_MouseX = mousePos.x;
			int m_MouseY = mousePos.y;
			if (m_MouseX > m_Width)
				m_MouseX = m_Width;
			else if (m_MouseX < 0)
				m_MouseX = 0;
			if (m_MouseY > m_Height)
				m_MouseY = m_Height;
			else if (m_MouseY < 0)
				m_MouseY = 0;

			DirectX::XMVECTOR localRayDirection = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
			DirectX::XMVECTOR LocalRayOrigin = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
			float X, Y, Z;
			DirectX::XMFLOAT4X4 camProjection;
			float fieldOfView = (float)DirectX::XM_PI / 4.0f;
			float screenAspect = (float)m_Width / (float)m_Height;

			DirectX::XMStoreFloat4x4(
				&camProjection,
				DirectX::XMMatrixPerspectiveFovLH(
					fieldOfView,
					screenAspect,
					0.1f,
					1000.0f)
			);

			//Transform 2D pick position on screen space to 3D ray in View space
			X = (((2.0f * m_MouseX) / m_Width) - 1) / camProjection._11;
			Y = -(((2.0f * m_MouseY) / m_Height) - 1) / camProjection._22;
			Z = 1.0f;    //View space's Z direction ranges from 0 to 1, so we set 1 since the ray goes "into" the screen

			localRayDirection = DirectX::XMVectorSet(X, Y, Z, 0.0f);

			DirectX::XMMATRIX inverseCamView;
			DirectX::XMVECTOR det = { 1,1,1,1 };
			DirectX::XMMATRIX temp;
			this->m_Camera->GetBaseViewMatrix(temp);

			//inverseCamView = DirectX::XMMatrixInverse(&det, temp);

			//rayOrigin = XMVector3TransformCoord(LocalRayOrigin, inverseCamView);
			//rayDirection = DirectX::XMVector3TransformNormal(localRayDirection, inverseCamView);
			//rayDirection = DirectX::XMVector3Normalize(rayDirection);

			DirectX::XMFLOAT4 test;
			DirectX::XMStoreFloat4(&test, localRayDirection);
			this->m_Camera->SetLookAt(test);
		}
	}
#pragma endregion
#pragma region SHIFT +
	if (keyBoardState[DIK_LSHIFT] & 0x80)
	{
		if (keyBoardState[DIK_W] & 0x80)
		{
			translateCameraZ += speed;
		}
		if (keyBoardState[DIK_S] & 0x80)
		{
			translateCameraZ -= speed;
		}
		if (keyBoardState[DIK_A] & 0x80)
		{
			translateCameraX -= speed;
		}
		if (keyBoardState[DIK_D] & 0x80)
		{
			translateCameraX += speed;
		}
		if (keyBoardState[DIK_C] & 0x80)
		{
			translateCameraY -= speed;
		}
		if (keyBoardState[DIK_SPACE] & 0x80)
		{
			translateCameraY += speed;
		}
		if (mouseCurrentState.rgbButtons[0])
		{
			if (mouseCurrentState.lY < 0)
			{
				translateCameraZ += speedrot;
			}
			if (mouseCurrentState.lY > 0)
			{
				translateCameraZ -= speedrot;
			}

		}

	}
#pragma endregion
	if (keyBoardState[DIK_LALT] & 0x80)
	{
		if (mouseCurrentState.rgbButtons[0])
		{
			if ((mouseCurrentState.lX!= m_mouseLastState.lX) || (mouseCurrentState.lY != m_mouseLastState.lY))
			{
				pitch += mouseCurrentState.lX * 0.01f;

				yaw += mouseCurrentState.lY * 0.01f;

				// Ensure the mouse location doesn't exceed the screen width or height.
				if (m_MouseX < 0) { m_MouseX = 0; }
				if (m_MouseY < 0) { m_MouseY = 0; }

				if (m_MouseX > m_Width) { m_MouseX = m_Width; }
				if (m_MouseY > m_Height) { m_MouseY = m_Height; }

				m_mouseLastState = mouseCurrentState;
			}
		}
	}

	if ((translateCameraY || translateCameraZ || translateCameraX))
	{
		DirectX::XMFLOAT3 posTranslation =
			DirectX::XMFLOAT3(
				float(translateCameraX),
				float(translateCameraY),
				float(translateCameraZ)
			);

		this->m_PreviousPos = this->m_Camera->GetCameraPos();
		this->m_Camera->ApplyLocalTranslation(
			float(translateCameraX),
			float(translateCameraY),
			float(translateCameraZ)
		);
		//this->m_Camera->AddToCameraPos(posTranslation);
		//this->m_Camera->AddToLookAt(posTranslation);
		this->m_Camera->Update();
	}

		float rotationAmount = DirectX::XM_PI / 8;

		DirectX::XMFLOAT4 newRotation =
			DirectX::XMFLOAT4(
				yaw * DirectX::XMScalarSin(rotationAmount / 2.0f),
				pitch * DirectX::XMScalarSin(rotationAmount / 2.0f),
				0.0f,
				DirectX::XMScalarCos(rotationAmount / 2.0f)
			);

		this->m_Camera->SetRotation(newRotation);
		//this->m_Camera->ApplyRotation(newRotation);
		this->m_Camera->Update();
	this->m_Camera->Update();
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <cstring>
#include <string>
#include <vector>
#include <regex>
#include <iterator>

#include <popt.h>

#include "defs.hh"
#include "io.hh"
#include "StringSet.hh"
#include "FactorGraph.hh"
#include "FactorEncoder.hh"
#include "Unigrams.hh"
#include "Bigrams.hh"

using namespace std;

void trim(string& str, char to_trim)
{
  string::size_type pos = str.find_last_not_of(to_trim);
  if(pos != string::npos) {
    str.erase(pos + 1);
    pos = str.find_first_not_of(to_trim);
    if(pos != string::npos) str.erase(0, pos);
  }
  else str.erase(str.begin(), str.end());
}

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

    char *vocab_fname;
    char *trans_fname;
    string in_fname;
    string out_fname_1;
    string out_fname_2;
    int maxlen;
    map<string, flt_type> vocab;
    StringSet *ss_vocab = NULL;
    transitions_t transitions;
    string start_end_symbol("*");
    flt_type one_char_min_lp = -25.0;
    bool enable_forward_backward = false;
    bool weights = false;

    poptContext pc;
    struct poptOption po[] = {
        {"vocabulary", 'v', POPT_ARG_STRING, &vocab_fname, 11001, NULL, "Vocabulary file name"},
        {"transitions", 't', POPT_ARG_STRING, &trans_fname, 11002, NULL, "Transition file name"},
        {"forward_backward", 'f', POPT_ARG_NONE, &enable_forward_backward, 11007, "Use Forward-backward segmentation instead of Viterbi", NULL},
        {"weights", 'w', POPT_ARG_NONE, &weights, 11007, "Training examples are weighted", NULL},
        POPT_AUTOHELP
        {NULL}
    };

    pc = poptGetContext(NULL, argc, (const char **)argv, po, 0);
    poptSetOtherOptionHelp(pc, "INPUT COUNTS1 COUNTS2");

    int val;
    while ((val = poptGetNextOpt(pc)) >= 0)
        continue;

    // poptGetNextOpt returns -1 when the final argument has been parsed
    // otherwise an error occured
    if (val != -1) {
        switch (val) {
        case POPT_ERROR_NOARG:
            cerr << "Argument missing for an option" << endl;
            exit(1);
        case POPT_ERROR_BADOPT:
            cerr << "Option's argument could not be parsed" << endl;
            exit(1);
        case POPT_ERROR_BADNUMBER:
        case POPT_ERROR_OVERFLOW:
            cerr << "Option could not be converted to number" << endl;
            exit(1);
        default:
            cerr << "Unknown error in option processing" << endl;
            exit(1);
        }
    }

    if (poptPeekArg(pc) != NULL)
        in_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Input file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        out_fname_1.assign((char*)poptGetArg(pc));
    else {
        cerr << "1-gram count file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        out_fname_2.assign((char*)poptGetArg(pc));
    else {
        cerr << "2-gram count file not set" << endl;
        exit(1);
    }

    if (vocab_fname == NULL && trans_fname == NULL) {
        cerr << "Please define vocabulary or transitions" << endl;
        exit(0);
    }

    if (vocab_fname != NULL && trans_fname != NULL) {
        cerr << "Don't define both vocabulary and transitions" << endl;
        exit(0);
    }

    if (vocab_fname != NULL) {
        cerr << "Reading vocabulary " << vocab_fname << endl;
        int retval = Unigrams::read_vocab(vocab_fname, vocab, maxlen);
        if (retval < 0) {
            cerr << "something went wrong reading vocabulary" << endl;
            exit(0);
        }
        cerr << "\t" << "size: " << vocab.size() << endl;
        cerr << "\t" << "maximum string length: " << maxlen << endl;
        ss_vocab = new StringSet(vocab);
    }

    if (trans_fname != NULL) {
        cerr << "Reading transitions " << trans_fname << endl;
        int retval = Bigrams::read_transitions(transitions, trans_fname);
        Bigrams::trans_to_vocab(transitions, vocab);
        ss_vocab = new StringSet(vocab);
        if (retval < 0) {
            cerr << "something went wrong reading transitions" << endl;
            exit(0);
        }
        cerr << "\t" << "vocabulary: " << transitions.size() << endl;
        cerr << "\t" << "transitions: " << retval << endl;
    }

    cerr << "Segmenting corpus" << endl;
    io::Stream infile;
    try {
        infile.open(in_fname, "r");
    }
    catch (io::Stream::OpenError oe) {
        cerr << "Something went wrong opening the input." << endl;
        exit(0);
    }

    map<string, flt_type> unigram_stats;
    transitions_t trans_stats;
    char linebuffer[8192];
    while (fgets(linebuffer, 8192 , infile.file) != NULL) {

        linebuffer[strlen(linebuffer)-1] = '\0';
        string line(linebuffer);

        flt_type curr_weight = 1.0;
        if (weights) {
            string remainder;
            std::istringstream iss(line);
            iss >> std::skipws >> curr_weight;
            getline(iss, remainder);
            trim(remainder, '\t'); trim(remainder,' ');
            line.assign(remainder);
        }

        for (int i=0; i<line.size(); i++) {
            string currchr {line[i]};
            if (!ss_vocab->includes(currchr))
                ss_vocab->add(currchr, one_char_min_lp);
        }

        transitions_t curr_stats;
        FactorGraph fg(line, start_end_symbol, *ss_vocab);

        // Unigram model
        if (vocab_fname != NULL)
            if (enable_forward_backward)
                forward_backward(vocab, fg, curr_stats);
            else {
                cout << "No implementation for Viterbi unigram yet." << endl;
            }
        // Bigram model
        else {
            if (enable_forward_backward)
                forward_backward(transitions, fg, curr_stats);
            else
                viterbi(transitions, fg, curr_stats);
        }

        Bigrams::update_trans_stats(curr_stats, curr_weight,
                                    trans_stats, unigram_stats);
    }

    if (ss_vocab != NULL) delete ss_vocab;

    Unigrams::write_vocab(out_fname_1, unigram_stats, true);
    Bigrams::write_transitions(trans_stats, out_fname_2, true);

    exit(1);
}

<commit_msg>Removed unused includes.<commit_after>#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <cstring>
#include <string>
#include <vector>

#include <popt.h>

#include "defs.hh"
#include "io.hh"
#include "StringSet.hh"
#include "FactorGraph.hh"
#include "FactorEncoder.hh"
#include "Unigrams.hh"
#include "Bigrams.hh"

using namespace std;

void trim(string& str, char to_trim)
{
  string::size_type pos = str.find_last_not_of(to_trim);
  if(pos != string::npos) {
    str.erase(pos + 1);
    pos = str.find_first_not_of(to_trim);
    if(pos != string::npos) str.erase(0, pos);
  }
  else str.erase(str.begin(), str.end());
}

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

    char *vocab_fname;
    char *trans_fname;
    string in_fname;
    string out_fname_1;
    string out_fname_2;
    int maxlen;
    map<string, flt_type> vocab;
    StringSet *ss_vocab = NULL;
    transitions_t transitions;
    string start_end_symbol("*");
    flt_type one_char_min_lp = -25.0;
    bool enable_forward_backward = false;
    bool weights = false;

    poptContext pc;
    struct poptOption po[] = {
        {"vocabulary", 'v', POPT_ARG_STRING, &vocab_fname, 11001, NULL, "Vocabulary file name"},
        {"transitions", 't', POPT_ARG_STRING, &trans_fname, 11002, NULL, "Transition file name"},
        {"forward_backward", 'f', POPT_ARG_NONE, &enable_forward_backward, 11007, "Use Forward-backward segmentation instead of Viterbi", NULL},
        {"weights", 'w', POPT_ARG_NONE, &weights, 11007, "Training examples are weighted", NULL},
        POPT_AUTOHELP
        {NULL}
    };

    pc = poptGetContext(NULL, argc, (const char **)argv, po, 0);
    poptSetOtherOptionHelp(pc, "INPUT COUNTS1 COUNTS2");

    int val;
    while ((val = poptGetNextOpt(pc)) >= 0)
        continue;

    // poptGetNextOpt returns -1 when the final argument has been parsed
    // otherwise an error occured
    if (val != -1) {
        switch (val) {
        case POPT_ERROR_NOARG:
            cerr << "Argument missing for an option" << endl;
            exit(1);
        case POPT_ERROR_BADOPT:
            cerr << "Option's argument could not be parsed" << endl;
            exit(1);
        case POPT_ERROR_BADNUMBER:
        case POPT_ERROR_OVERFLOW:
            cerr << "Option could not be converted to number" << endl;
            exit(1);
        default:
            cerr << "Unknown error in option processing" << endl;
            exit(1);
        }
    }

    if (poptPeekArg(pc) != NULL)
        in_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Input file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        out_fname_1.assign((char*)poptGetArg(pc));
    else {
        cerr << "1-gram count file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        out_fname_2.assign((char*)poptGetArg(pc));
    else {
        cerr << "2-gram count file not set" << endl;
        exit(1);
    }

    if (vocab_fname == NULL && trans_fname == NULL) {
        cerr << "Please define vocabulary or transitions" << endl;
        exit(0);
    }

    if (vocab_fname != NULL && trans_fname != NULL) {
        cerr << "Don't define both vocabulary and transitions" << endl;
        exit(0);
    }

    if (vocab_fname != NULL) {
        cerr << "Reading vocabulary " << vocab_fname << endl;
        int retval = Unigrams::read_vocab(vocab_fname, vocab, maxlen);
        if (retval < 0) {
            cerr << "something went wrong reading vocabulary" << endl;
            exit(0);
        }
        cerr << "\t" << "size: " << vocab.size() << endl;
        cerr << "\t" << "maximum string length: " << maxlen << endl;
        ss_vocab = new StringSet(vocab);
    }

    if (trans_fname != NULL) {
        cerr << "Reading transitions " << trans_fname << endl;
        int retval = Bigrams::read_transitions(transitions, trans_fname);
        Bigrams::trans_to_vocab(transitions, vocab);
        ss_vocab = new StringSet(vocab);
        if (retval < 0) {
            cerr << "something went wrong reading transitions" << endl;
            exit(0);
        }
        cerr << "\t" << "vocabulary: " << transitions.size() << endl;
        cerr << "\t" << "transitions: " << retval << endl;
    }

    cerr << "Segmenting corpus" << endl;
    io::Stream infile;
    try {
        infile.open(in_fname, "r");
    }
    catch (io::Stream::OpenError oe) {
        cerr << "Something went wrong opening the input." << endl;
        exit(0);
    }

    map<string, flt_type> unigram_stats;
    transitions_t trans_stats;
    char linebuffer[8192];
    while (fgets(linebuffer, 8192 , infile.file) != NULL) {

        linebuffer[strlen(linebuffer)-1] = '\0';
        string line(linebuffer);

        flt_type curr_weight = 1.0;
        if (weights) {
            string remainder;
            std::istringstream iss(line);
            iss >> std::skipws >> curr_weight;
            getline(iss, remainder);
            trim(remainder, '\t'); trim(remainder,' ');
            line.assign(remainder);
        }

        for (int i=0; i<line.size(); i++) {
            string currchr {line[i]};
            if (!ss_vocab->includes(currchr))
                ss_vocab->add(currchr, one_char_min_lp);
        }

        transitions_t curr_stats;
        FactorGraph fg(line, start_end_symbol, *ss_vocab);

        // Unigram model
        if (vocab_fname != NULL)
            if (enable_forward_backward)
                forward_backward(vocab, fg, curr_stats);
            else {
                cout << "No implementation for Viterbi unigram yet." << endl;
            }
        // Bigram model
        else {
            if (enable_forward_backward)
                forward_backward(transitions, fg, curr_stats);
            else
                viterbi(transitions, fg, curr_stats);
        }

        Bigrams::update_trans_stats(curr_stats, curr_weight,
                                    trans_stats, unigram_stats);
    }

    if (ss_vocab != NULL) delete ss_vocab;

    Unigrams::write_vocab(out_fname_1, unigram_stats, true);
    Bigrams::write_transitions(trans_stats, out_fname_2, true);

    exit(1);
}

<|endoftext|>


<commit_before>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#pragma once
#include"boost/spirit/home/support/common_terminals.hpp"
#include"boost/spirit/home/qi.hpp"
#include"ork/ork.hpp"

/*
Placeholders for parser components
*/
namespace ork {
namespace orq {//ork-qi :)

BOOST_SPIRIT_TERMINAL(id);
BOOST_SPIRIT_TERMINAL(quote);
BOOST_SPIRIT_TERMINAL(lb_com);//'pound comment'

}//namespace orq
}//namespace ork

/*
Enablers for parser components
*/
namespace boost {
namespace spirit {

//Make custom parser usable as a terminal only, and only for parser expressions (qi::domain).
template<> struct use_terminal<qi::domain, ork::orq::tag::id> : mpl::true_ {};
template<> struct use_terminal<qi::domain, ork::orq::tag::quote> : mpl::true_ {};
template<> struct use_terminal<qi::domain, ork::orq::tag::lb_com> : mpl::true_ {};

}//namespace spirit
}//namespace boost

namespace ork {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace ascii = spirit::ascii;
namespace proto = boost::proto;

#if ORK_UNICODE
typedef spirit::char_encoding::standard_wide charset;
#else
typedef spirit::char_encoding::standard charset;
#endif

namespace orq {//ork-qi :)

struct ORK_ORK_API id_parser : qi::primitive_parser<id_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef string type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		if(first == last) {
			return false;
		}

		iter it(first);
		if(!std::isalpha(*it) && *it != ORK('_')) {
			return false;//First character must be letter or underscore
		}
		while(it != last && (std::isalnum(*it) || *it == ORK('_'))) {
			++it;//Subsequent characters can be numbers also
		}

		attribute result(first, it);
		if(result.empty()) {
			return false;
		}

		first = it;
		spirit::traits::assign_to(result, attr);
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("id");
	}
};

struct ORK_ORK_API quote_parser : qi::primitive_parser<quote_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef string type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		if(first == last) {
			return false;
		}

		iter it(first);
		if(*it++ != ORK('"')) {//Consume the quote
			return false;
		}
		while(it != last && *it != ORK('"')) {//Up to but do not consume the quote
			++it;
		}
		if(it == last) {
			return false;
		}
		if(*it++ != ORK('"')) {//Consume the quote
			return false;
		}

		attribute result(++first, it - 1);//Do not include quotes
		//Allow empty attribute

		first = it;
		spirit::traits::assign_to(result, attr);
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("quote");
	}
};

struct ORK_ORK_API lb_com_parser : qi::primitive_parser<lb_com_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef qi::unused_type type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		if(first == last) {
			return false;
		}

		iter it(first);
		if(*it++ != ORK('#')) {//Consume the marker
			return false;
		}
		while(it != last && *it != ORK('\n')) {//Up to but do not consume the eol
			++it;
		}

		first = it;
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("lb_com");
	}
};

}//namespace orq
}//namespace ork

/*
Instantiators for parser components
*/
namespace boost {
namespace spirit {
namespace qi {

//This is the factory function object that is invoked to create an instance of our parser.
#define ORK_ORQ_FACTORY(TAG)\
template<typename modifiers>\
struct make_primitive<ork::orq::tag::TAG, modifiers> {\
	typedef typename ork::orq::ORK_CAT(TAG,_parser) result_type;\
	result_type operator()(unused_type, unused_type) const {\
		return result_type();\
	}\
};

ORK_ORQ_FACTORY(id);
ORK_ORQ_FACTORY(quote);
ORK_ORQ_FACTORY(lb_com);

}//namespace qi
}//namespace spirit
}//namespace boost<commit_msg>Refactored identifier code into function<commit_after>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#pragma once
#include"boost/spirit/home/support/common_terminals.hpp"
#include"boost/spirit/home/qi.hpp"
#include"ork/ork.hpp"

/*
Placeholders for parser components
*/
namespace ork {
namespace orq {//ork-qi :)

BOOST_SPIRIT_TERMINAL(id);
BOOST_SPIRIT_TERMINAL(quote);
BOOST_SPIRIT_TERMINAL(lb_com);//'pound comment'

}//namespace orq
}//namespace ork

/*
Enablers for parser components
*/
namespace boost {
namespace spirit {

//Make custom parser usable as a terminal only, and only for parser expressions (qi::domain).
template<> struct use_terminal<qi::domain, ork::orq::tag::id> : mpl::true_ {};
template<> struct use_terminal<qi::domain, ork::orq::tag::quote> : mpl::true_ {};
template<> struct use_terminal<qi::domain, ork::orq::tag::lb_com> : mpl::true_ {};

}//namespace spirit
}//namespace boost

namespace ork {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace ascii = spirit::ascii;
namespace proto = boost::proto;

#if ORK_UNICODE
typedef spirit::char_encoding::standard_wide charset;
#else
typedef spirit::char_encoding::standard charset;
#endif

namespace orq {//ork-qi :)

namespace detail {

template<typename iter>
bool consume_identifier(iter& it, const iter&first, const iter& last) {
	if(it == last) {
		return false;
	}

	if(!std::isalpha(*it) && *it != ORK('_')) {
		return false;//First character must be letter or underscore
	}
	while(it != last && (std::isalnum(*it) || *it == ORK('_'))) {
		++it;//Subsequent characters can be numbers also
	}

	return it != first;
}

}//namespace detail

struct ORK_ORK_API id_parser : qi::primitive_parser<id_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef string type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		iter it(first);
		if(!detail::consume_identifier(it, first, last)) {
			return false;
		}

		attribute result(first, it);
		first = it;
		spirit::traits::assign_to(result, attr);
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("id");
	}
};

struct ORK_ORK_API quote_parser : qi::primitive_parser<quote_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef string type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		if(first == last) {
			return false;
		}

		iter it(first);
		if(*it++ != ORK('"')) {//Consume the quote
			return false;
		}
		while(it != last && *it != ORK('"')) {//Up to but do not consume the quote
			++it;
		}
		if(it == last) {
			return false;
		}
		if(*it++ != ORK('"')) {//Consume the quote
			return false;
		}

		attribute result(++first, it - 1);//Do not include quotes
		//Allow empty attribute

		first = it;
		spirit::traits::assign_to(result, attr);
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("quote");
	}
};

struct ORK_ORK_API lb_com_parser : qi::primitive_parser<lb_com_parser> {
public://Parser component stuff
	template<typename context, typename iter>
	struct attribute {//Define the attribute type exposed by this parser component
		typedef qi::unused_type type;
	};

	//This function is called during the actual parsing process
	template<typename iter, typename context, typename skipper, typename attribute>
	bool parse(iter& first, const iter& last, context&ctxt, const skipper& skip, attribute& attr) const {
		boost::spirit::qi::skip_over(first, last, skip);//All primitive parsers pre-skip

		if(first == last) {
			return false;
		}

		iter it(first);
		if(*it++ != ORK('#')) {//Consume the marker
			return false;
		}
		while(it != last && *it != ORK('\n')) {//Up to but do not consume the eol
			++it;
		}

		first = it;
		return true;
	}

	//This function is called during error handling to create a human readable string for the error context.
	template<typename context>
	boost::spirit::info what(context&) const {
		return boost::spirit::info("lb_com");
	}
};

}//namespace orq
}//namespace ork

/*
Instantiators for parser components
*/
namespace boost {
namespace spirit {
namespace qi {

//This is the factory function object that is invoked to create an instance of our parser.
#define ORK_ORQ_FACTORY(TAG)\
template<typename modifiers>\
struct make_primitive<ork::orq::tag::TAG, modifiers> {\
	typedef typename ork::orq::ORK_CAT(TAG,_parser) result_type;\
	result_type operator()(unused_type, unused_type) const {\
		return result_type();\
	}\
};

ORK_ORQ_FACTORY(id);
ORK_ORQ_FACTORY(quote);
ORK_ORQ_FACTORY(lb_com);

}//namespace qi
}//namespace spirit
}//namespace boost<|endoftext|>


<commit_before>/*
    Copyright (C) 2014  P.L. Lucas <selairi@gmail.com>
    Copyright (C) 2013  <copyright holder> <email>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "monitorsettingsdialog.h"

#include "monitorwidget.h"
#include "monitor.h"
#include "timeoutdialog.h"
#include "monitorpicture.h"
#include "settingsdialog.h"
#include "fastmenu.h"

#include <KScreen/Output>
#include <QJsonObject>
#include <QJsonArray>
#include <LXQt/Settings>
#include <QJsonDocument>
#include <KScreen/EDID>
#include <QFile>
#include <QDir>
#include <QFileInfo>
#include <QMessageBox>
#include <QDateTime>
#include <lxqtautostartentry.h>

MonitorSettingsDialog::MonitorSettingsDialog() :
    QDialog(nullptr, 0)
{
    ui.setupUi(this);

    KScreen::GetConfigOperation *operation = new KScreen::GetConfigOperation();
    connect(operation, &KScreen::GetConfigOperation::finished, [this, operation] (KScreen::ConfigOperation *op) {
        KScreen::GetConfigOperation *configOp = qobject_cast<KScreen::GetConfigOperation *>(op);
        qDebug() << "Connecting to KScreen...";
        if (configOp && configOp->config() && configOp->config()->screen())
        {
            mOldConfig = configOp->config()->clone();
            loadConfiguration(configOp->config());
            operation->deleteLater();
        }
        else if(configOp && !configOp->config())
        {
            qDebug() << "Error: Config is invalid, probably backend couldn't load";
            exit(1);
        }
        else if(configOp && configOp->config() && !configOp->config()->screen())
        {
            qDebug() << "Error: No screen in the configuration, broken backend";
            exit(2);
        }
        else
        {
            qDebug() << "Error: Connect to KScreen is not possible";
            exit(3);
        }
    });

    connect(ui.buttonBox, &QDialogButtonBox::clicked, [&] (QAbstractButton *button) {
        if (ui.buttonBox->standardButton(button) == QDialogButtonBox::Apply)
            applyConfiguration(false);
        if (ui.buttonBox->standardButton(button) == QDialogButtonBox::Save)
        {
            applyConfiguration(true);
        }

    });

    connect(ui.settingsButton, SIGNAL(clicked()), this, SLOT(showSettingsDialog()));
}

MonitorSettingsDialog::~MonitorSettingsDialog()
{
}

void MonitorSettingsDialog::loadConfiguration(KScreen::ConfigPtr config)
{
    if (mConfig == config)
        return;

    mConfig = config;

    MonitorPictureDialog *monitorPicture = nullptr;
    FastMenu *fastMenu = nullptr;
    KScreen::OutputList outputs = mConfig->outputs();

    int nMonitors = 0;
    for (const KScreen::OutputPtr &output : outputs)
    {
        if (output->isConnected())
            nMonitors++;

        if (nMonitors > 1)
        {
            fastMenu = new FastMenu(config, this);
            ui.monitorList->addItem(tr("Fast Menu"));
            ui.stackedWidget->addWidget(fastMenu);

            monitorPicture = new MonitorPictureDialog(config, this);
            ui.monitorList->addItem(tr("Set position"));
            ui.stackedWidget->addWidget(monitorPicture);
            break;
        }
    }

    QList<MonitorWidget*> monitors;

    for (const KScreen::OutputPtr &output : outputs)
    {
        if (output->isConnected())
        {
            MonitorWidget *monitor = new MonitorWidget(output, mConfig, this);
            ui.monitorList->addItem(output->name() + " " + output->edid()->name() + " " + output->edid()->vendor());
            ui.stackedWidget->addWidget(monitor);
            monitors.append(monitor);
        }
    }

    for(const MonitorWidget *monitor1 : qAsConst(monitors))
    {
        for(const MonitorWidget *monitor : qAsConst(monitors))
        {
            if(monitor != monitor1)
                connect(monitor, SIGNAL(primaryOutputChanged(MonitorWidget *)), monitor1, SLOT(onPrimaryOutputChanged(MonitorWidget *)));
        }
    }

    if (monitorPicture)
        monitorPicture->setScene(monitors);

    ui.monitorList->setCurrentRow(0);
    adjustSize();
}

void MonitorSettingsDialog::applyConfiguration(bool saveConfigOk)
{
    if (mConfig && KScreen::Config::canBeApplied(mConfig))
    {
        KScreen::SetConfigOperation(mConfig).exec();

        TimeoutDialog mTimeoutDialog;
        if (mTimeoutDialog.exec() == QDialog::Rejected)
            KScreen::SetConfigOperation(mOldConfig).exec();
        else
        {
            mOldConfig = mConfig->clone();
            if (saveConfigOk)
                saveConfiguration(mConfig);
        }
    }
}

void MonitorSettingsDialog::accept()
{
    //applyConfiguration(true);
    QDialog::accept();
}

void MonitorSettingsDialog::reject()
{
    QDialog::reject();
}

void MonitorSettingsDialog::saveConfiguration(KScreen::ConfigPtr config)
{

    QList<MonitorSettings> currentSettings;
    KScreen::OutputList outputs = config->outputs();
    for (const KScreen::OutputPtr &output : outputs)
    {
        MonitorSettings monitor;
        monitor.name = output->name();
        KScreen::Edid* edid = output->edid();
        if (edid && edid->isValid())
            monitor.hash = edid->hash();
        monitor.connected = output->isConnected();
        if ( output->isConnected() )
        {
            monitor.enabled = output->isEnabled();
            monitor.primary = output->isPrimary();
            monitor.xPos = output->pos().x();
            monitor.yPos = output->pos().y();
            monitor.currentMode = output->currentModeId();
            monitor.currentModeWidth = output->currentMode()->size().width();
            monitor.currentModeHeight = output->currentMode()->size().height();
            monitor.currentModeRate = output->currentMode()->refreshRate();
            monitor.rotation = output->rotation();
        }
        currentSettings.append(monitor);
    }

    LXQt::Settings settings("lxqt-config-monitor");
    settings.beginGroup("currentConfig");
    saveMonitorSettings(settings, currentSettings);
    settings.endGroup();

    QList<MonitorSavedSettings> monitors;
    settings.beginGroup("SavedConfigs");
    loadMonitorSettings(settings, monitors);
    qDebug() << "[ MonitorSettingsDialog::saveConfiguration] # monitors Read:" << monitors.size();
    MonitorSavedSettings monitor;
    monitor.name = QDateTime::currentDateTime().toString();
    monitor.date = QDateTime::currentDateTime().toString(Qt::ISODate);
    monitor.monitors = currentSettings;
    monitors.append(monitor);
    saveMonitorSettings(settings, monitors);
    qDebug() << "[ MonitorSettingsDialog::saveConfiguration] # monitors Write:" << monitors.size();
    settings.endGroup();

    LXQt::AutostartEntry autoStart("lxqt-config-monitor-autostart.desktop");
    XdgDesktopFile desktopFile(XdgDesktopFile::ApplicationType, "lxqt-config-monitor-autostart", "lxqt-config-monitor -l");
    //desktopFile.setValue("OnlyShowIn", QString(qgetenv("XDG_CURRENT_DESKTOP")));
    desktopFile.setValue("OnlyShowIn", "LXQt");
    desktopFile.setValue("Comment", "Autostart monitor settings for LXQt-config-monitor");
    autoStart.setFile(desktopFile);
    autoStart.commit();
}

void MonitorSettingsDialog::showSettingsDialog()
{
    QByteArray configName = qgetenv("LXQT_SESSION_CONFIG");

    if (configName.isEmpty())
        configName = "MonitorSettings";

    LXQt::Settings settings(configName);

    SettingsDialog settingsDialog(tr("Advanced settings"), &settings, mConfig);
    settingsDialog.exec();
}
<commit_msg>Brackets added to monitor name.<commit_after>/*
    Copyright (C) 2014  P.L. Lucas <selairi@gmail.com>
    Copyright (C) 2013  <copyright holder> <email>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "monitorsettingsdialog.h"

#include "monitorwidget.h"
#include "monitor.h"
#include "timeoutdialog.h"
#include "monitorpicture.h"
#include "settingsdialog.h"
#include "fastmenu.h"

#include <KScreen/Output>
#include <QJsonObject>
#include <QJsonArray>
#include <LXQt/Settings>
#include <QJsonDocument>
#include <KScreen/EDID>
#include <QFile>
#include <QDir>
#include <QFileInfo>
#include <QMessageBox>
#include <QDateTime>
#include <lxqtautostartentry.h>

MonitorSettingsDialog::MonitorSettingsDialog() :
    QDialog(nullptr, 0)
{
    ui.setupUi(this);

    KScreen::GetConfigOperation *operation = new KScreen::GetConfigOperation();
    connect(operation, &KScreen::GetConfigOperation::finished, [this, operation] (KScreen::ConfigOperation *op) {
        KScreen::GetConfigOperation *configOp = qobject_cast<KScreen::GetConfigOperation *>(op);
        qDebug() << "Connecting to KScreen...";
        if (configOp && configOp->config() && configOp->config()->screen())
        {
            mOldConfig = configOp->config()->clone();
            loadConfiguration(configOp->config());
            operation->deleteLater();
        }
        else if(configOp && !configOp->config())
        {
            qDebug() << "Error: Config is invalid, probably backend couldn't load";
            exit(1);
        }
        else if(configOp && configOp->config() && !configOp->config()->screen())
        {
            qDebug() << "Error: No screen in the configuration, broken backend";
            exit(2);
        }
        else
        {
            qDebug() << "Error: Connect to KScreen is not possible";
            exit(3);
        }
    });

    connect(ui.buttonBox, &QDialogButtonBox::clicked, [&] (QAbstractButton *button) {
        if (ui.buttonBox->standardButton(button) == QDialogButtonBox::Apply)
            applyConfiguration(false);
        if (ui.buttonBox->standardButton(button) == QDialogButtonBox::Save)
        {
            applyConfiguration(true);
        }

    });

    connect(ui.settingsButton, SIGNAL(clicked()), this, SLOT(showSettingsDialog()));
}

MonitorSettingsDialog::~MonitorSettingsDialog()
{
}

void MonitorSettingsDialog::loadConfiguration(KScreen::ConfigPtr config)
{
    if (mConfig == config)
        return;

    mConfig = config;

    MonitorPictureDialog *monitorPicture = nullptr;
    FastMenu *fastMenu = nullptr;
    KScreen::OutputList outputs = mConfig->outputs();

    int nMonitors = 0;
    for (const KScreen::OutputPtr &output : outputs)
    {
        if (output->isConnected())
            nMonitors++;

        if (nMonitors > 1)
        {
            fastMenu = new FastMenu(config, this);
            ui.monitorList->addItem(tr("Fast Menu"));
            ui.stackedWidget->addWidget(fastMenu);

            monitorPicture = new MonitorPictureDialog(config, this);
            ui.monitorList->addItem(tr("Set position"));
            ui.stackedWidget->addWidget(monitorPicture);
            break;
        }
    }

    QList<MonitorWidget*> monitors;

    for (const KScreen::OutputPtr &output : outputs)
    {
        if (output->isConnected())
        {
            MonitorWidget *monitor = new MonitorWidget(output, mConfig, this);
            QString monitorName = output->edid()->name() + " " + output->edid()->vendor();
            if(monitorName.trimmed().size() > 0)
                monitorName = "(" + monitorName + ")";
            ui.monitorList->addItem(output->name() + " " + monitorName);
            ui.stackedWidget->addWidget(monitor);
            monitors.append(monitor);
        }
    }

    for(const MonitorWidget *monitor1 : qAsConst(monitors))
    {
        for(const MonitorWidget *monitor : qAsConst(monitors))
        {
            if(monitor != monitor1)
                connect(monitor, SIGNAL(primaryOutputChanged(MonitorWidget *)), monitor1, SLOT(onPrimaryOutputChanged(MonitorWidget *)));
        }
    }

    if (monitorPicture)
        monitorPicture->setScene(monitors);

    ui.monitorList->setCurrentRow(0);
    adjustSize();
}

void MonitorSettingsDialog::applyConfiguration(bool saveConfigOk)
{
    if (mConfig && KScreen::Config::canBeApplied(mConfig))
    {
        KScreen::SetConfigOperation(mConfig).exec();

        TimeoutDialog mTimeoutDialog;
        if (mTimeoutDialog.exec() == QDialog::Rejected)
            KScreen::SetConfigOperation(mOldConfig).exec();
        else
        {
            mOldConfig = mConfig->clone();
            if (saveConfigOk)
                saveConfiguration(mConfig);
        }
    }
}

void MonitorSettingsDialog::accept()
{
    //applyConfiguration(true);
    QDialog::accept();
}

void MonitorSettingsDialog::reject()
{
    QDialog::reject();
}

void MonitorSettingsDialog::saveConfiguration(KScreen::ConfigPtr config)
{

    QList<MonitorSettings> currentSettings;
    KScreen::OutputList outputs = config->outputs();
    for (const KScreen::OutputPtr &output : outputs)
    {
        MonitorSettings monitor;
        monitor.name = output->name();
        KScreen::Edid* edid = output->edid();
        if (edid && edid->isValid())
            monitor.hash = edid->hash();
        monitor.connected = output->isConnected();
        if ( output->isConnected() )
        {
            monitor.enabled = output->isEnabled();
            monitor.primary = output->isPrimary();
            monitor.xPos = output->pos().x();
            monitor.yPos = output->pos().y();
            monitor.currentMode = output->currentModeId();
            monitor.currentModeWidth = output->currentMode()->size().width();
            monitor.currentModeHeight = output->currentMode()->size().height();
            monitor.currentModeRate = output->currentMode()->refreshRate();
            monitor.rotation = output->rotation();
        }
        currentSettings.append(monitor);
    }

    LXQt::Settings settings("lxqt-config-monitor");
    settings.beginGroup("currentConfig");
    saveMonitorSettings(settings, currentSettings);
    settings.endGroup();

    QList<MonitorSavedSettings> monitors;
    settings.beginGroup("SavedConfigs");
    loadMonitorSettings(settings, monitors);
    qDebug() << "[ MonitorSettingsDialog::saveConfiguration] # monitors Read:" << monitors.size();
    MonitorSavedSettings monitor;
    monitor.name = QDateTime::currentDateTime().toString();
    monitor.date = QDateTime::currentDateTime().toString(Qt::ISODate);
    monitor.monitors = currentSettings;
    monitors.append(monitor);
    saveMonitorSettings(settings, monitors);
    qDebug() << "[ MonitorSettingsDialog::saveConfiguration] # monitors Write:" << monitors.size();
    settings.endGroup();

    LXQt::AutostartEntry autoStart("lxqt-config-monitor-autostart.desktop");
    XdgDesktopFile desktopFile(XdgDesktopFile::ApplicationType, "lxqt-config-monitor-autostart", "lxqt-config-monitor -l");
    //desktopFile.setValue("OnlyShowIn", QString(qgetenv("XDG_CURRENT_DESKTOP")));
    desktopFile.setValue("OnlyShowIn", "LXQt");
    desktopFile.setValue("Comment", "Autostart monitor settings for LXQt-config-monitor");
    autoStart.setFile(desktopFile);
    autoStart.commit();
}

void MonitorSettingsDialog::showSettingsDialog()
{
    QByteArray configName = qgetenv("LXQT_SESSION_CONFIG");

    if (configName.isEmpty())
        configName = "MonitorSettings";

    LXQt::Settings settings(configName);

    SettingsDialog settingsDialog(tr("Advanced settings"), &settings, mConfig);
    settingsDialog.exec();
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "MarbleDirs.h"

#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtGui/QApplication>

#ifdef Q_OS_MACX
//for getting app bundle path
#include <ApplicationServices/ApplicationServices.h>
#endif

#include <config-marble.h>

namespace
{
    QString runTimeMarbleDataPath = "";
}

MarbleDirs::MarbleDirs()
    : d( 0 )
{
}

QString MarbleDirs::path( const QString& relativePath )
{
    QString  localpath = localPath() + QDir::separator() + relativePath;	// local path
//    qDebug( "localpath: %s", qPrintable( localpath ) );
    QString  systempath  = systemPath() + QDir::separator() + relativePath;	// system path
//    qDebug( "systempath: %s", qPrintable( systempath ) );

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }
//    qDebug( "Using path: %s", qPrintable( fullpath ) );

    return QDir( fullpath ).canonicalPath();
}

QString MarbleDirs::systemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/data";
    }
/*
    // tackat: If I understood tim correctly this should
    //         now be obsolete, right?
    else //must be running from a non .app bundle
    {
      systempath = QApplication::applicationDirPath()+"/../share/data";
    }
*/
    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarbleDataPath.isEmpty() )
    return runTimeMarbleDataPath;

#if !defined(Q_OS_WIN)
    //MARBLE_DATA_PATH is a compiler define set by cmake
    QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);
//    qDebug( "%s <-- marble data path", qPrintable( compileTimeMarbleDataPath ) );

    return compileTimeMarbleDataPath;
#endif

return QDir( qApp->applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/data" )
#else
                     + QLatin1String( "/../share/apps/marble/data" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::localPath()
{
    return QString( QDir::homePath() + "/.marble/data" ); // local path
}

QString MarbleDirs::marbleDataPath()
{
    return runTimeMarbleDataPath;
}

void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarbleDataPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarbleDataPath = adaptedPath;
}
<commit_msg>fix data search path for kde version of marble for Windows<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "MarbleDirs.h"

#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtGui/QApplication>

#ifdef Q_OS_MACX
//for getting app bundle path
#include <ApplicationServices/ApplicationServices.h>
#endif

#include <config-marble.h>

namespace
{
    QString runTimeMarbleDataPath = "";
}

MarbleDirs::MarbleDirs()
    : d( 0 )
{
}

QString MarbleDirs::path( const QString& relativePath )
{
    QString  localpath = localPath() + QDir::separator() + relativePath;	// local path
//    qDebug( "localpath: %s", qPrintable( localpath ) );
    QString  systempath  = systemPath() + QDir::separator() + relativePath;	// system path
//    qDebug( "systempath: %s", qPrintable( systempath ) );

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }
//    qDebug( "Using path: %s", qPrintable( fullpath ) );

    return QDir( fullpath ).canonicalPath();
}

QString MarbleDirs::systemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/data";
    }
/*
    // tackat: If I understood tim correctly this should
    //         now be obsolete, right?
    else //must be running from a non .app bundle
    {
      systempath = QApplication::applicationDirPath()+"/../share/data";
    }
*/
    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarbleDataPath.isEmpty() )
    return runTimeMarbleDataPath;

#ifdef MARBLE_DATA_PATH
    //MARBLE_DATA_PATH is a compiler define set by cmake
    QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);
//    qDebug( "%s <-- marble data path", qPrintable( compileTimeMarbleDataPath ) );

    return compileTimeMarbleDataPath;
#endif

return QDir( qApp->applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/data" )
#else
                     + QLatin1String( "/../share/apps/marble/data" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::localPath()
{
    return QString( QDir::homePath() + "/.marble/data" ); // local path
}

QString MarbleDirs::marbleDataPath()
{
    return runTimeMarbleDataPath;
}

void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarbleDataPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarbleDataPath = adaptedPath;
}
<|endoftext|>


<commit_before>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#ifndef OPENCV_VERSION_HPP
#define OPENCV_VERSION_HPP

#define CV_VERSION_MAJOR    4
#define CV_VERSION_MINOR    5
#define CV_VERSION_REVISION 2
#define CV_VERSION_STATUS   "-pre"

#define CVAUX_STR_EXP(__A)  #__A
#define CVAUX_STR(__A)      CVAUX_STR_EXP(__A)

#define CVAUX_STRW_EXP(__A)  L ## #__A
#define CVAUX_STRW(__A)      CVAUX_STRW_EXP(__A)

#define CV_VERSION          CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) CV_VERSION_STATUS

/* old  style version constants*/
#define CV_MAJOR_VERSION    CV_VERSION_MAJOR
#define CV_MINOR_VERSION    CV_VERSION_MINOR
#define CV_SUBMINOR_VERSION CV_VERSION_REVISION

#endif // OPENCV_VERSION_HPP
<commit_msg>release: OpenCV 4.5.2<commit_after>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#ifndef OPENCV_VERSION_HPP
#define OPENCV_VERSION_HPP

#define CV_VERSION_MAJOR    4
#define CV_VERSION_MINOR    5
#define CV_VERSION_REVISION 2
#define CV_VERSION_STATUS   ""

#define CVAUX_STR_EXP(__A)  #__A
#define CVAUX_STR(__A)      CVAUX_STR_EXP(__A)

#define CVAUX_STRW_EXP(__A)  L ## #__A
#define CVAUX_STRW(__A)      CVAUX_STRW_EXP(__A)

#define CV_VERSION          CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) CV_VERSION_STATUS

/* old  style version constants*/
#define CV_MAJOR_VERSION    CV_VERSION_MAJOR
#define CV_MINOR_VERSION    CV_VERSION_MINOR
#define CV_SUBMINOR_VERSION CV_VERSION_REVISION

#endif // OPENCV_VERSION_HPP
<|endoftext|>