<commit_before>#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>
#include <vector>

#include "board.h"
#include "emit.h"
#include "io_functions.h"
#include "load.h"
#include "options.h"

option::Option *options;

int main(int argc, char *argv[]){
	// process arguments
	option::Stats stats(usage, argc - 1, argv + 1);
	option::Option _options[stats.options_max], buffer[stats.buffer_max];
	option::Parser parse(usage, argc - 1, argv + 1, _options, buffer);

	options = _options;

	if(parse.error())
		return -1;

	if(options[OPT_HELP] || argc == 1){
		option::printUsage(std::cout, usage);
		return 0;
	}

	for(option::Option *opt = options[OPT_UNKNOWN]; opt; opt = opt->next())
		emit_warning(std::string("Unknown option: ") + opt->name);

	if(parse.nonOptionsCount() == 0){
		emit_error("No input file");
		return -2;
	}

	std::string filename = parse.nonOption(0);
	// load
	std::srand(std::time(nullptr));
	prepare_io(true);
	std::vector<Board> boards;
	std::map<std::string, unsigned> lookup;
	if(!load_mbl_file(filename, boards, lookup)){
		emit_error("Could not load file " + filename);
		return -3;
	}

	// get highest input
	int highest_input = 0;
	for(int i = 36; i --> 0;){
		if(!boards[0].inputs[i].empty()){
			highest_input = i;
			break;
		}
	}

	// check arguments
	if(parse.nonOptionsCount() != 2 + highest_input){ // filename + (highest_input + 1)
		emit_error("Expected " + std::to_string(highest_input + 1) + " inputs, got " + std::to_string(parse.nonOptionsCount() - 1));
		return -4;
	}
	BoardCall bc{&boards[0], 0, 0};
	uint8_t inputs[36] = { 0 };
	uint16_t outputs[36], output_left, output_right;

	for(int i = 0; i <= highest_input; ++i){
		if(!boards[0].inputs[i].empty()){
			std::string opt = parse.nonOption(i);
			unsigned value;
			std::istringstream iss(opt);
			iss >> value;
			if(iss.fail()){
				emit_error("Argument value " + opt + " is not an nonnegative integer");
				return -5;
			}
			if(value > 255){
				emit_warning("Argument value " + opt + " is larger than 255; using value mod 256");
				value &= 255;
			}
			inputs[i] = value;
		}
	}

	bc.call(inputs, outputs, output_left, output_right);

	prepare_io(false);

	return (outputs[0] >> 8) ? outputs[0] & 0xFF : 0;
}
<commit_msg>Fixed arg number for MB args; number parsing<commit_after>#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>
#include <vector>

#include "board.h"
#include "emit.h"
#include "io_functions.h"
#include "load.h"
#include "options.h"

option::Option *options;

int main(int argc, char *argv[]){
	// process arguments
	option::Stats stats(usage, argc - 1, argv + 1);
	option::Option _options[stats.options_max], buffer[stats.buffer_max];
	option::Parser parse(usage, argc - 1, argv + 1, _options, buffer);

	options = _options;

	if(parse.error())
		return -1;

	if(options[OPT_HELP] || argc == 1){
		option::printUsage(std::cout, usage);
		return 0;
	}

	for(option::Option *opt = options[OPT_UNKNOWN]; opt; opt = opt->next())
		emit_warning(std::string("Unknown option: ") + opt->name);

	if(parse.nonOptionsCount() == 0){
		emit_error("No input file");
		return -2;
	}

	std::string filename = parse.nonOption(0);
	// load
	std::srand(std::time(nullptr));
	prepare_io(true);
	std::vector<Board> boards;
	std::map<std::string, unsigned> lookup;
	if(!load_mbl_file(filename, boards, lookup)){
		emit_error("Could not load file " + filename);
		return -3;
	}

	// get highest input
	int highest_input = 0;
	for(int i = 36; i --> 0;){
		if(!boards[0].inputs[i].empty()){
			highest_input = i;
			break;
		}
	}

	// check arguments
	if(parse.nonOptionsCount() != 2 + highest_input){ // filename + (highest_input + 1)
		emit_error("Expected " + std::to_string(highest_input + 1) + " inputs, got " + std::to_string(parse.nonOptionsCount() - 1));
		return -4;
	}
	BoardCall bc{&boards[0], 0, 0};
	uint8_t inputs[36] = { 0 };
	uint16_t outputs[36], output_left, output_right;

	for(int i = 0; i <= highest_input; ++i){
		if(!boards[0].inputs[i].empty()){
			std::string opt = parse.nonOption(i + 1);
			unsigned value = 0;
			bool too_large = false;
			for(auto c : opt){
				if(std::isdigit(c)){
					value = 10 * value + (c - '0');
					if(value > 255)
						too_large = true;
				}else{
					emit_error("Argument value " + opt + " is not a nonnegative integer");
				}
			}
			if(too_large){
				emit_warning("Argument value " + opt + " is larger than 255; using value mod 256");
			}
			inputs[i] = value & 255;
		}
	}

	bc.call(inputs, outputs, output_left, output_right);

	prepare_io(false);

	return (outputs[0] >> 8) ? outputs[0] & 0xFF : 0;
}
<|endoftext|>


<commit_before>

<commit_msg>Added charge/discharge/fire functionality<commit_after>#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <chrono>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

using namespace ::std;

class I2CBus
{
  public:
    I2CBus(unsigned _busId)
     :m_busFd(-1),
      m_busPath()
    {
      ostringstream busDevName;
      busDevName << "/dev/i2c-" << _busId;
      m_busPath = busDevName.str();
      m_busFd = ::open(m_busPath.c_str(), O_RDWR | O_SYNC);
      if (m_busFd == -1)
      {
        ostringstream os;
        os << "cannot open i2c bus device " << m_busPath;
        throw runtime_error(os.str());
      }
    }

    ~I2CBus()
    {
      if (m_busFd != -1)
        ::close(m_busFd);
    }

    int           fd()   const { return m_busFd; }
    const string& path() const { return m_busPath; }

  private:
    int    m_busFd;
    string m_busPath;
};

class I2CDevice
{
  public:
    I2CDevice(unsigned _busId, unsigned _deviceId)
     :m_i2cBus(_busId)
    {
      if (ioctl(m_i2cBus.fd(), I2C_SLAVE, &_deviceId) != 0)
      {
        ostringstream os;
        os << "cannot select i2c slave device " << _deviceId << ", bus " << m_i2cBus.path();
        throw runtime_error(os.str());
      }
    }

    template <typename UInt, size_t _bytes = sizeof(UInt)>
    bool readUInt(UInt& _data)
    {
      uint8_t dataBuf[_bytes];
      if (::read(m_i2cBus.fd(), dataBuf, sizeof(dataBuf)) != sizeof(dataBuf))
        return false;

      _data = UInt();
      for (size_t idx = 0; idx < _bytes; ++idx)
        _data |= static_cast<UInt>(dataBuf[idx]) << (idx*8);
      return true;
    }

    template <typename UInt, size_t _bytes = sizeof(UInt)>
    bool writeUInt(const UInt& _data)
    {
      uint8_t dataBuf[_bytes];
      for (size_t idx = 0; idx < _bytes; ++idx)
        dataBuf[idx] = static_cast<uint8_t>(_data >> (idx*8));

      if (::write(m_i2cBus.fd(), dataBuf, sizeof(dataBuf)) != sizeof(dataBuf))
        return false;
      return true;
    }

  private:
    I2CBus m_i2cBus;
};

class MSPControl
{
  public:
    MSPControl(unsigned _busId, unsigned _deviceId)
     :m_i2cDevice(_busId, _deviceId)
    {
    }

    unsigned readWord(unsigned _addr)
    {
      uint8_t addr = static_cast<uint8_t>(_addr);
      if (!m_i2cDevice.writeUInt(addr))
      {
        ostringstream os;
        os << "cannot write cmd";
        throw runtime_error(os.str());
      }

      uint16_t result;
      if (!m_i2cDevice.readUInt(result))
      {
        ostringstream os;
        os << "cannot read result";
        throw runtime_error(os.str());
      }

      return result;
    }

  private:
    I2CDevice m_i2cDevice;
};

class GPIOControl
{
  public:
    GPIOControl(unsigned _gpio)
     :m_gpioFd(-1),
      m_gpioPath()
    {
      ostringstream gpioCtrlName;
      gpioCtrlName << "/sys/class/gpio/gpio" << _gpio << "/value";
      m_gpioPath = gpioCtrlName.str();
      m_gpioFd = ::open(m_gpioPath.c_str(), O_RDWR | O_SYNC);
      if (m_gpioFd == -1)
      {
        ostringstream os;
        os << "cannot open gpio control " << m_gpioPath;
        throw runtime_error(os.str());
      }
    }

    ~GPIOControl()
    {
      if (m_gpioFd != -1)
        ::close(m_gpioFd);
    }

    void setValue(unsigned _val)
    {
      ostringstream valueStream;
      valueStream << _val << endl;
      const string& value = valueStream.str();
      if (::write(m_gpioFd, value.c_str(), value.length()) != value.length())
      {
        ostringstream os;
        os << "cannot set gpio value " << m_gpioPath;
        throw runtime_error(os.str());
      }
    }

    const string& path() const { return m_gpioPath; }

  private:
    int m_gpioFd;
    string m_gpioPath;
};

class TrikCoilGun
{
  public:
    TrikCoilGun(unsigned _mspBusId, unsigned _mspDeviceId,
                unsigned _mspChargeLevelCmd, unsigned _mspDischargeCurrentCmd,
                unsigned _gpioChargeControl, unsigned _gpioDischargeControl)
     :m_mspControl(_mspBusId, _mspDeviceId),
      m_mspCmdChargeLevel(_mspChargeLevelCmd),
      m_mspCmdDischargeCurrent(_mspDischargeCurrentCmd),
      m_gpioChargeControl(_gpioChargeControl),
      m_gpioDischargeControl(_gpioDischargeControl)
    {
      m_gpioChargeControl.setValue(0);
      m_gpioDischargeControl.setValue(0);
    }

    ~TrikCoilGun()
    {
      m_gpioChargeControl.setValue(0);
      m_gpioDischargeControl.setValue(0);
    }

    void charge(unsigned _durationMs, unsigned _chargeLevel)
    {
      const chrono::steady_clock::time_point& startAt = chrono::steady_clock::now();
      const bool waitCharge = _durationMs == 0;
      const chrono::steady_clock::time_point& elapseAt = startAt + chrono::duration<chrono::steady_clock::rep, chrono::milliseconds::period>(_durationMs);

#if 1
      cerr << "Preparing for charge" << endl;
      bool charging = false;
#endif
      while (true)
      {
        if (!waitCharge && chrono::steady_clock::now() >= elapseAt)
          break;

        if (m_mspControl.readWord(m_mspCmdChargeLevel) >= _chargeLevel)
        {
#if 1
          if (charging)
            cerr << "Stop charging" << endl;
          charging = false;
#endif
          if (waitCharge)
            break;
          m_gpioChargeControl.setValue(0);
        }
        else
        {
#if 1
          if (!charging)
            cerr << "Charging" << endl;
          charging = true;
#endif
          m_gpioChargeControl.setValue(1);
        }
        usleep(1000);
      }
#if 1
      cerr << "Charge done" << endl;
#endif
      m_gpioChargeControl.setValue(0);
    }

    void discharge(unsigned _durationMs, unsigned _zeroChargeLevel)
    {
      const chrono::steady_clock::time_point& startAt = chrono::steady_clock::now();
      const bool waitDischarge = _durationMs == 0;
      const chrono::steady_clock::time_point& elapseAt = startAt + chrono::duration<chrono::steady_clock::rep, chrono::milliseconds::period>(_durationMs);

#if 1
      cerr << "Preparing for discharge" << endl;
#endif
      while (true)
      {
        if (!waitDischarge && chrono::steady_clock::now() >= elapseAt)
          break;

        if (m_mspControl.readWord(m_mspCmdChargeLevel) <= _zeroChargeLevel)
        {
#if 1
          cerr << "Discharged" << endl;
#endif
          break;
        }

        m_gpioDischargeControl.setValue(1);
        usleep(1000);
      }
#if 1
      cerr << "Discharge done" << endl;
#endif
      m_gpioDischargeControl.setValue(0);
    }

    void fire(unsigned _preDelayMs, unsigned _durationMs, unsigned _postDelayMs)
    {
      m_gpioChargeControl.setValue(0);
      usleep(_preDelayMs * 1000);
      m_gpioDischargeControl.setValue(1);
      usleep(_durationMs * 1000);
      m_gpioChargeControl.setValue(0);
      usleep(_postDelayMs * 1000);
    }

  private:
    MSPControl m_mspControl;
    unsigned m_mspCmdChargeLevel;
    unsigned m_mspCmdDischargeCurrent;
    GPIOControl m_gpioChargeControl;
    GPIOControl m_gpioDischargeControl;
};

#if 0

static int s_chargeLevel = 0;
static int s_chargeDurationMs = 0;
static int s_fireDurationMs = 10;
static int s_dischargeDelayMs = 100;
static int s_dischargeDurationMs = 0;
static int s_dischargeLevel = 0;

#endif

int main()
{
  TrikCoilGun coilGun(0,0,0,0,0,0);

  coilGun.charge(1000, 0);
  coilGun.fire(10, 10, 100);
  coilGun.discharge(1000, 0);
}

<|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*               Copyright 1998-2002 by Ullrich Koethe                  */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_ERROR_HXX
#define VIGRA_ERROR_HXX

#include <stdexcept>
#include <stdio.h>
#include <string>
#include "vigra/config.hxx"

/*! \page ErrorReporting Error Reporting
    Exceptions and assertions provided by VIGRA

    \#include "vigra/error.hxx"

    VIGRA defines the following exception classes:

    \code
    namespace vigra {
        class ContractViolation : public std::exception;
        class PreconditionViolation : public ContractViolation;
        class PostconditionViolation : public ContractViolation;
        class InvariantViolation : public ContractViolation;
    }
    \endcode

    The following associated macros throw the corresponding exception if
    their PREDICATE evaluates to '<TT>false</TT>':

    \code
    vigra_precondition(PREDICATE, MESSAGE);
    vigra_postcondition(PREDICATE, MESSAGE);
    vigra_invariant(PREDICATE, MESSAGE);
    \endcode

    The MESSAGE is passed to the exception and can be retrieved via
    the overloaded member function '<TT>exception.what()</TT>'. If the compiler
    flag '<TT>NDEBUG</TT>' is not defined, the file name and line number of
    the error are automatically included in the message.

    The following macro

    \code
    vigra_fail(MESSAGE);
    \endcode

    unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message
    (along with file name and line number, if NDEBUG is not set).

     Usage:

    Include-File:
    "vigra/error.hxx"

    Namespace: vigra (except for the macros, of course)

    \code
    int main(int argc, char ** argv)
    {
        try
        {
            const char* input_file_name = argv[1];

            // read input image
            vigra::ImageImportInfo info(input_file_name);

            // fail if input image is not grayscale
            vigra_precondition(info.isGrayscale(), "Input image must be grayscale");

            ...// process image
        }
        catch (std::exception & e)
        {
            std::cerr << e.what() << std::endl; // print message
            return 1;
        }

        return 0;
    }
    \endcode
**/

namespace vigra {

class ContractViolation : public StdException
{
  public:
    ContractViolation(char const * prefix, char const * message,
                      char const * file, int line)
    {
        sprintf(what_, "\n%.30s\n%.900s\n(%.100s:%d)\n", prefix, message, file, line);
    }

    ContractViolation(char const * prefix, char const * message)
    {
        sprintf(what_, "\n%.30s\n%.900s\n", prefix, message);
    }

    virtual const char * what() const throw()
    {
        return what_;
    }

  private:
    enum { bufsize_ = 1100 };
    char what_[bufsize_];
};

class PreconditionViolation : public ContractViolation
{
  public:
    PreconditionViolation(char const * message, const char * file, int line)
    : ContractViolation("Precondition violation!", message, file, line)
    {}

    PreconditionViolation(char const * message)
    : ContractViolation("Precondition violation!", message)
    {}
};

class PostconditionViolation : public ContractViolation
{
  public:
    PostconditionViolation(char const * message, const char * file, int line)
    : ContractViolation("Postcondition violation!", message, file, line)
    {}

    PostconditionViolation(char const * message)
    : ContractViolation("Postcondition violation!", message)
    {}
};

class InvariantViolation : public ContractViolation
{
  public:
    InvariantViolation(char const * message, const char * file, int line)
    : ContractViolation("Invariant violation!", message, file, line)
    {}

    InvariantViolation(char const * message)
    : ContractViolation("Invariant violation!", message)
    {}
};

#ifndef NDEBUG

inline
void throw_invariant_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message, file, line);
}

inline
void throw_invariant_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message.c_str(), file, line);
}

inline
void throw_precondition_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message, file, line);
}

inline
void throw_precondition_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message.c_str(), file, line);
}

inline
void throw_postcondition_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message, file, line);
}

inline
void throw_postcondition_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message.c_str(), file, line);
}

inline
void throw_runtime_error(char const * message, char const * file, int line)
{
    char what_[1100];
    sprintf(what_, "\n%.900s\n(%.100s:%d)\n", message, file, line);
    throw std::runtime_error(what_);
}

inline
void throw_runtime_error(std::string message, char const * file, int line)
{
    char what_[1100];
    sprintf(what_, "\n%.900s\n(%.100s:%d)\n", message.c_str(), file, line);
    throw std::runtime_error(what_);
}

#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_fail(MESSAGE) vigra::throw_runtime_error(MESSAGE, __FILE__, __LINE__)

#else // NDEBUG

inline
void throw_invariant_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message);
}

inline
void throw_precondition_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message);
}

inline
void throw_postcondition_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message);
}

inline
void throw_invariant_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message.c_str());
}

inline
void throw_precondition_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message.c_str());
}

inline
void throw_postcondition_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message.c_str());
}

#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE)

#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE)

#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE)

#define vigra_fail(MESSAGE) throw std::runtime_error(MESSAGE)

#endif // NDEBUG

} // namespace vigra

#endif // VIGRA_ERROR_HXX
<commit_msg>added vigra_assert()<commit_after>/************************************************************************/
/*                                                                      */
/*               Copyright 1998-2002 by Ullrich Koethe                  */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_ERROR_HXX
#define VIGRA_ERROR_HXX

#include <stdexcept>
#include <stdio.h>
#include <string>
#include "vigra/config.hxx"

/*! \page ErrorReporting Error Reporting
    Exceptions and assertions provided by VIGRA

    \#include "vigra/error.hxx"

    VIGRA defines the following exception classes:

    \code
    namespace vigra {
        class ContractViolation : public std::exception;
        class PreconditionViolation : public ContractViolation;
        class PostconditionViolation : public ContractViolation;
        class InvariantViolation : public ContractViolation;
    }
    \endcode

    The following associated macros throw the corresponding exception if
    their PREDICATE evaluates to '<TT>false</TT>':

    \code
    vigra_precondition(PREDICATE, MESSAGE);
    vigra_postcondition(PREDICATE, MESSAGE);
    vigra_invariant(PREDICATE, MESSAGE);
    \endcode

    The MESSAGE is passed to the exception and can be retrieved via
    the overloaded member function '<TT>exception.what()</TT>'. If the compiler
    flag '<TT>NDEBUG</TT>' is not defined, the file name and line number of
    the error are automatically included in the message. The macro

    \code
    vigra_assert(PREDICATE, MESSAGE);
    \endcode

    is identical to <tt>vigra_precondition()</tt> except that it is completely removed
    when '<TT>NDEBUG</TT>' is defined. This is useful for test that are only needed during
    debugging, such as array index bound checking. The following macro

    \code
    vigra_fail(MESSAGE);
    \endcode

    unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message
    (along with file name and line number, if NDEBUG is not set).

     Usage:

    Include-File:
    "vigra/error.hxx"

    Namespace: vigra (except for the macros, of course)

    \code
    int main(int argc, char ** argv)
    {
        try
        {
            const char* input_file_name = argv[1];

            // read input image
            vigra::ImageImportInfo info(input_file_name);

            // fail if input image is not grayscale
            vigra_precondition(info.isGrayscale(), "Input image must be grayscale");

            ...// process image
        }
        catch (std::exception & e)
        {
            std::cerr << e.what() << std::endl; // print message
            return 1;
        }

        return 0;
    }
    \endcode
**/

namespace vigra {

class ContractViolation : public StdException
{
  public:
    ContractViolation(char const * prefix, char const * message,
                      char const * file, int line)
    {
        sprintf(what_, "\n%.30s\n%.900s\n(%.100s:%d)\n", prefix, message, file, line);
    }

    ContractViolation(char const * prefix, char const * message)
    {
        sprintf(what_, "\n%.30s\n%.900s\n", prefix, message);
    }

    virtual const char * what() const throw()
    {
        return what_;
    }

  private:
    enum { bufsize_ = 1100 };
    char what_[bufsize_];
};

class PreconditionViolation : public ContractViolation
{
  public:
    PreconditionViolation(char const * message, const char * file, int line)
    : ContractViolation("Precondition violation!", message, file, line)
    {}

    PreconditionViolation(char const * message)
    : ContractViolation("Precondition violation!", message)
    {}
};

class PostconditionViolation : public ContractViolation
{
  public:
    PostconditionViolation(char const * message, const char * file, int line)
    : ContractViolation("Postcondition violation!", message, file, line)
    {}

    PostconditionViolation(char const * message)
    : ContractViolation("Postcondition violation!", message)
    {}
};

class InvariantViolation : public ContractViolation
{
  public:
    InvariantViolation(char const * message, const char * file, int line)
    : ContractViolation("Invariant violation!", message, file, line)
    {}

    InvariantViolation(char const * message)
    : ContractViolation("Invariant violation!", message)
    {}
};

#ifndef NDEBUG

inline
void throw_invariant_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message, file, line);
}

inline
void throw_invariant_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message.c_str(), file, line);
}

inline
void throw_precondition_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message, file, line);
}

inline
void throw_precondition_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message.c_str(), file, line);
}

inline
void throw_postcondition_error(bool predicate, char const * message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message, file, line);
}

inline
void throw_postcondition_error(bool predicate, std::string message, char const * file, int line)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message.c_str(), file, line);
}

inline
void throw_runtime_error(char const * message, char const * file, int line)
{
    char what_[1100];
    sprintf(what_, "\n%.900s\n(%.100s:%d)\n", message, file, line);
    throw std::runtime_error(what_);
}

inline
void throw_runtime_error(std::string message, char const * file, int line)
{
    char what_[1100];
    sprintf(what_, "\n%.900s\n(%.100s:%d)\n", message.c_str(), file, line);
    throw std::runtime_error(what_);
}

#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_assert(PREDICATE, MESSAGE) vigra_precondition(PREDICATE, MESSAGE)

#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE, __FILE__, __LINE__)

#define vigra_fail(MESSAGE) vigra::throw_runtime_error(MESSAGE, __FILE__, __LINE__)

#else // NDEBUG

inline
void throw_invariant_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message);
}

inline
void throw_precondition_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message);
}

inline
void throw_postcondition_error(bool predicate, char const * message)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message);
}

inline
void throw_invariant_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::InvariantViolation(message.c_str());
}

inline
void throw_precondition_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::PreconditionViolation(message.c_str());
}

inline
void throw_postcondition_error(bool predicate, std::string message)
{
    if(!predicate)
	   throw vigra::PostconditionViolation(message.c_str());
}

#define vigra_precondition(PREDICATE, MESSAGE) vigra::throw_precondition_error((PREDICATE), MESSAGE)

#define vigra_assert(PREDICATE, MESSAGE)

#define vigra_postcondition(PREDICATE, MESSAGE) vigra::throw_postcondition_error((PREDICATE), MESSAGE)

#define vigra_invariant(PREDICATE, MESSAGE) vigra::throw_invariant_error((PREDICATE), MESSAGE)

#define vigra_fail(MESSAGE) throw std::runtime_error(MESSAGE)

#endif // NDEBUG

} // namespace vigra

#endif // VIGRA_ERROR_HXX
<|endoftext|>


<commit_before>#include "Command.h"
#include "Test.h"
#include "Or.h"
#include "And.h"
#include "Semicolon.h"

#include <sys/stat.h>
#include <stack>
#include <queue>

// split word into tokens and put them in a vector of char*
void parse(string keyword, vector<char*> &wordList)
{
    char *cs = new char[keyword.length()];
    for (unsigned i = 0; i < keyword.length(); i++)
    {
        cs[i] = keyword[i];
    }
    cs[keyword.length()] = '\0';        //add the null terminator at the end of

    char *tokens = strtok(cs, " ");
    while (tokens)
    {
        wordList.push_back(tokens);
        tokens = strtok(NULL, " ");
    }
}

void copy(char** &arr, vector<char*>& v)
{
    v.push_back(NULL);
    arr = new char*[v.size()];
    for (unsigned i = 0; i < v.size(); i++)
    {
        arr[i] = v.at(i);
    }
}

int main()
{
    string input;

    while (1)           // shell should run indefinitely unless exited
    {

        cout << "$ ";
        getline(cin, input);                        // get whole command line

        if(input == "exit")
        {
            exit(0);
            break;
        }

        vector<char*> words;
        parse(input, words);

        queue<string> connectors;
        stack<cmdComponent*> commands;

        // for (unsigned a = 0; a < words.size(); a++)
        // {
        //     cout << words.at(a) << endl;
        // }

        //break up the vector of words into commands
        vector<char*> argv;
        for (unsigned i = 0; i < words.size(); i++)
        {
            char *sc  = (char*) memchr (words.at(i), ';', strlen(words.at(i)));
            char *And = (char*) memchr (words.at(i), '&', strlen(words.at(i)));
            char *Or  = (char*) memchr (words.at(i), '|', strlen(words.at(i)));
            char *com = (char*) memchr (words.at(i), '#', strlen(words.at(i)));

            if ( (sc == NULL && Or == NULL && And == NULL) )
            {
                if ( (com == NULL) && (i == (words.size() - 1)) )
                {
                    argv.push_back(words.at(i));
                    char** args;
                    copy(args, argv);
                    if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                    {
                        Test* tst = new Test();
                        tst->setTest(args);
                        commands.push(tst);
                    }
                    else
                    {
                        Command* com = new Command();
                        com->setCommand(args);
                        commands.push(com);
                    }
                    argv.clear();
                }
                else if (com == NULL)
                {
                    argv.push_back(words.at(i));
                }
                else
                {
                    char** args;
                    copy(args, argv);
                    if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                    {
                        Test* tst = new Test();
                        tst->setTest(args);
                        commands.push(tst);
                    }
                    else
                    {
                        Command* com = new Command();
                        com->setCommand(args);
                        commands.push(com);
                    }
                    argv.clear();
                    break;
                }
            }
            else
            {
                string type = "";
                if (sc)
                {
                    type = ";";
                    connectors.push(type);
                }
                else if (And)
                {
                    type = "&&";
                    connectors.push(type);
                }
                else
                {
                    type = "||";
                    connectors.push(type);
                }

                char** args;
                copy(args, argv);
                if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                {
                    Test* tst = new Test();
                    tst->setTest(args);
                    commands.push(tst);
                }
                else
                {
                    Command* com = new Command();
                    com->setCommand(args);
                    commands.push(com);
                }
                argv.clear();
            }
        }

        //cout << "commands size:" << commands.size() << endl;
        //set up the command tree
        if (commands.size() > connectors.size())
        {
            //cout << "command queue size: " << commands.size() << endl;
            stack<cmdComponent*> stack;

            while (!commands.empty())
            {
                stack.push(commands.top());
                commands.pop();
            }

            //cout <<"stack size before tree:" << stack.size() << endl;
            while ((!connectors.empty()) && !stack.empty())
            {
                cmdComponent* tleft = stack.top();
                stack.pop();
                cmdComponent* tright = stack.top();
                stack.pop();

                cmdComponent* tmp;

                if (connectors.front() == ";")
                {
                    tmp = new Semicolon(tleft, tright);
                }
                else if (connectors.front() == "&&")
                {
                    tmp = new And(tleft, tright);
                }
                else
                {
                    tmp = new Or(tleft, tright);
                }
                stack.push(tmp);
                connectors.pop();
            }

            // finally execute tree of commands
            if (!stack.empty())
            {
                stack.top()->execute();
            }

        }
        else
        {
            if (commands.size() == 0)
            {

            }
            else
            {
                cout << "Error: Invalid input" << endl;
            }
        }

    }

    return 0;
}

<commit_msg>various clarity changes<commit_after>#include "Command.h"
#include "Test.h"
#include "Or.h"
#include "And.h"
#include "Semicolon.h"

#include <sys/stat.h>
#include <stack>
#include <queue>

// split word into tokens and put them in a vector of char*
void parse(string keyword, vector<char*> &wordList)
{
    char *cs = new char[keyword.length()];
    for (unsigned i = 0; i < keyword.length(); i++)
    {
        cs[i] = keyword[i];
    }
    cs[keyword.length()] = '\0';        //add the null terminator at the end of

    char *tokens = strtok(cs, " ");
    while (tokens)
    {
        wordList.push_back(tokens);
        tokens = strtok(NULL, " ");
    }
}

// copies a vector<char*> to a char* array
void copy(char** &arr, vector<char*>& v)
{
    v.push_back(NULL);
    arr = new char*[v.size()];
    for (unsigned i = 0; i < v.size(); i++)
    {
        arr[i] = v.at(i);
    }
}

int main()
{
    string input;

    while (1)           // shell should run indefinitely unless exited
    {

        cout << "$ ";
        getline(cin, input);        // get whole command line

        if(input == "exit")
        {
            exit(0);
            break;
        }

        queue<string> connectors;
        stack<cmdComponent*> commands;
        vector<char*> words;
        parse(input, words);

        //break up the vector of words into commands
        vector<char*> argv;
        for (unsigned i = 0; i < words.size(); i++)
        {
            char *sc  = (char*) memchr (words.at(i), ';', strlen(words.at(i)));
            char *And = (char*) memchr (words.at(i), '&', strlen(words.at(i)));
            char *Or  = (char*) memchr (words.at(i), '|', strlen(words.at(i)));
            char *com = (char*) memchr (words.at(i), '#', strlen(words.at(i)));

            if ( (sc == NULL && Or == NULL && And == NULL) )
            {
                if ( (com == NULL) && (i == (words.size() - 1)) )
                {
                    argv.push_back(words.at(i));
                    char** args;
                    copy(args, argv);
                    if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                    {
                        Test* tst = new Test();
                        tst->setTest(args);
                        commands.push(tst);
                    }
                    else
                    {
                        Command* com = new Command();
                        com->setCommand(args);
                        commands.push(com);
                    }
                    argv.clear();
                }
                else if (com == NULL)
                {
                    argv.push_back(words.at(i));
                }
                else
                {
                    char** args;
                    copy(args, argv);
                    if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                    {
                        Test* tst = new Test();
                        tst->setTest(args);
                        commands.push(tst);
                    }
                    else
                    {
                        Command* com = new Command();
                        com->setCommand(args);
                        commands.push(com);
                    }
                    argv.clear();
                    break;
                }
            }
            else
            {
                string type = "";
                if (sc)
                {
                    type = ";";
                    connectors.push(type);
                }
                else if (And)
                {
                    type = "&&";
                    connectors.push(type);
                }
                else
                {
                    type = "||";
                    connectors.push(type);
                }

                char** args;
                copy(args, argv);
                if((string(argv.at(0)) == "test") || (string(argv.at(0)) == "["))
                {
                    Test* tst = new Test();
                    tst->setTest(args);
                    commands.push(tst);
                }
                else
                {
                    Command* com = new Command();
                    com->setCommand(args);
                    commands.push(com);
                }
                argv.clear();
            }
        } //done breaking up words into commands

        //set up the command tree
        if (commands.size() > connectors.size())
        {
            //cout << "command queue size: " << commands.size() << endl;
            stack<cmdComponent*> stack;

            while (!commands.empty())
            {
                stack.push(commands.top());
                commands.pop();
            }

            while ((!connectors.empty()) && !stack.empty())
            {
                cmdComponent* tleft = stack.top();
                stack.pop();
                cmdComponent* tright = stack.top();
                stack.pop();

                cmdComponent* tmp;

                if (connectors.front() == ";")
                {
                    tmp = new Semicolon(tleft, tright);
                }
                else if (connectors.front() == "&&")
                {
                    tmp = new And(tleft, tright);
                }
                else
                {
                    tmp = new Or(tleft, tright);
                }
                stack.push(tmp);
                connectors.pop();
            }

            // finally execute tree of commands
            if (!stack.empty())
            {
                stack.top()->execute();
            }

        }
        else
        {
            if (commands.size() == 0)
            {
                // do nothing
            }
            else
            {
                cout << "Error: Invalid input" << endl;
            }
        }

    } // end of infinite while loop

    return 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <ospray.h>
#include <ospcommon/vec.h>
#include "gl_core_3_3.h"
#define TINYOBJLOADER_IMPLEMENTATION
#include "tiny_obj_loader.h"

static int WIN_WIDTH = 1280;
static int WIN_HEIGHT = 720;

int main(int argc, const char **argv) {
	if (argc < 2) {
		std::cerr << "You must specify a model to render\n";
		return 1;
	}
	const std::string model_file = argv[1];
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
		std::cerr << "Failed to initialize SDL\n";
		return 1;
	}
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
#ifndef NDEBUG
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
#endif

	SDL_Window *win = SDL_CreateWindow("OSPRay-vive", SDL_WINDOWPOS_CENTERED,
			SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, SDL_WINDOW_OPENGL);
	if (!win){
		std::cout << "Failed to open SDL window: " << SDL_GetError() << "\n";
		return 1;
	}
	SDL_GLContext ctx = SDL_GL_CreateContext(win);
	if (!ctx){
		std::cout << "Failed to get OpenGL context: " << SDL_GetError() << "\n";
		return 1;
	}
	if (ogl_LoadFunctions() == ogl_LOAD_FAILED){
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to Load OpenGL Functions",
				"Could not load OpenGL functions for 3.3, OpenGL 3.3 or higher is required",
				NULL);
		SDL_GL_DeleteContext(ctx);
		SDL_DestroyWindow(win);
		SDL_Quit();
		return 1;
	}
	SDL_GL_SetSwapInterval(1);

	GLuint fbo, texture;
	glGenFramebuffers(1, &fbo);
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIN_WIDTH, WIN_HEIGHT, 0, GL_RGBA,
			GL_UNSIGNED_BYTE, nullptr);

	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	ospInit(&argc, argv);

	using namespace ospcommon;
	const vec2i imageSize(WIN_WIDTH, WIN_HEIGHT);
	const vec3f camPos(0, 2.5, 5);
	const vec3f camDir = -camPos;
	const vec3f camUp(0, 1, 0);

	OSPCamera camera = ospNewCamera("perspective");
	ospSetf(camera, "aspect", imageSize.x / static_cast<float>(imageSize.y));
	ospSetVec3f(camera, "pos", (osp::vec3f&)camPos);
	ospSetVec3f(camera, "dir", (osp::vec3f&)camDir);
	ospSetVec3f(camera, "up",  (osp::vec3f&)camUp);
	ospCommit(camera);

	// Load the model w/ tinyobjloader
	tinyobj::attrib_t attrib;
	std::vector<tinyobj::shape_t> shapes;
	std::vector<tinyobj::material_t> materials;
	std::string err;
	bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, model_file.c_str(),
			nullptr, true);
	if (!err.empty()) {
		std::cerr << "Error loading model: " << err << "\n";
	}
	if (!ret) {
		return 1;
	}

	OSPModel world = ospNewModel();

	// Load all the objects into ospray
	OSPData pos_data = ospNewData(attrib.vertices.size() / 3, OSP_FLOAT3,
			attrib.vertices.data(), OSP_DATA_SHARED_BUFFER);
	ospCommit(pos_data);

	for (size_t s = 0; s < shapes.size(); ++s) {
		std::cout << "Loading mesh " << shapes[s].name
			<< ", has " << shapes[s].mesh.indices.size() << " vertices\n";
		const tinyobj::mesh_t &mesh = shapes[s].mesh;
		std::vector<int32_t> indices;
		indices.reserve(mesh.indices.size());
		for (const auto &idx : mesh.indices) {
			indices.push_back(idx.vertex_index);
		}
		OSPData idx_data = ospNewData(indices.size() / 3, OSP_INT3, indices.data());
		ospCommit(idx_data);
		OSPGeometry geom = ospNewGeometry("triangles");
		ospSetObject(geom, "vertex", pos_data);
		ospSetObject(geom, "index", idx_data);
		ospCommit(geom);
		ospAddGeometry(world, geom);
	}
	ospCommit(world);

	OSPRenderer renderer = ospNewRenderer("ao");
	ospSetObject(renderer, "model", world);
	ospSetObject(renderer, "camera", camera);
	ospSetVec3f(renderer, "bgColor", (osp::vec3f&)vec3f(0.05, 0.05, 0.05));
	ospCommit(renderer);

	OSPFrameBuffer framebuffer = ospNewFrameBuffer((osp::vec2i&)imageSize, OSP_FB_SRGBA,
			OSP_FB_COLOR | OSP_FB_ACCUM);
	ospFrameBufferClear(framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM);

	bool quit = false;
	while (!quit){
		SDL_Event e;
		while (SDL_PollEvent(&e)){
			if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)){
				quit = true;
				break;
			}
		}
		ospFrameBufferClear(framebuffer, OSP_FB_COLOR);
		ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
		const uint32_t *fb = static_cast<const uint32_t*>(ospMapFrameBuffer(framebuffer, OSP_FB_COLOR));
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIN_WIDTH, WIN_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, fb);
		ospUnmapFrameBuffer(fb, framebuffer);

		glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		glBlitFramebuffer(0, 0, WIN_WIDTH, WIN_HEIGHT, 0, 0, WIN_WIDTH, WIN_HEIGHT,
				GL_COLOR_BUFFER_BIT, GL_NEAREST);

		SDL_GL_SwapWindow(win);
	}

	SDL_GL_DeleteContext(ctx);
	SDL_DestroyWindow(win);
	SDL_Quit();
	return 0;
}

<commit_msg>now in stereo<commit_after>#include <iostream>
#include <vector>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <ospray.h>
#include <ospcommon/vec.h>
#include "gl_core_3_3.h"
#define TINYOBJLOADER_IMPLEMENTATION
#include "tiny_obj_loader.h"

static int WIN_WIDTH = 1280;
static int WIN_HEIGHT = 720;

int main(int argc, const char **argv) {
	if (argc < 2) {
		std::cerr << "You must specify a model to render\n";
		return 1;
	}
	const std::string model_file = argv[1];
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
		std::cerr << "Failed to initialize SDL\n";
		return 1;
	}
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
#ifndef NDEBUG
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
#endif

	SDL_Window *win = SDL_CreateWindow("OSPRay-vive", SDL_WINDOWPOS_CENTERED,
			SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, SDL_WINDOW_OPENGL);
	if (!win){
		std::cout << "Failed to open SDL window: " << SDL_GetError() << "\n";
		return 1;
	}
	SDL_GLContext ctx = SDL_GL_CreateContext(win);
	if (!ctx){
		std::cout << "Failed to get OpenGL context: " << SDL_GetError() << "\n";
		return 1;
	}
	if (ogl_LoadFunctions() == ogl_LOAD_FAILED){
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to Load OpenGL Functions",
				"Could not load OpenGL functions for 3.3, OpenGL 3.3 or higher is required",
				NULL);
		SDL_GL_DeleteContext(ctx);
		SDL_DestroyWindow(win);
		SDL_Quit();
		return 1;
	}
	SDL_GL_SetSwapInterval(1);

	GLuint fbo, texture;
	glGenFramebuffers(1, &fbo);
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIN_WIDTH, WIN_HEIGHT, 0, GL_RGBA,
			GL_UNSIGNED_BYTE, nullptr);

	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	ospInit(&argc, argv);

	using namespace ospcommon;
	const vec2i imageSize(WIN_WIDTH, WIN_HEIGHT);
	const vec3f camPos(0, 2.5, 5);
	const vec3f camDir = vec3f(0, 1, 0) - camPos;
	const vec3f camUp(0, 1, 0);

	OSPCamera camera = ospNewCamera("perspective");
	ospSetf(camera, "aspect", imageSize.x / static_cast<float>(imageSize.y));
	ospSet1i(camera, "stereoMode", 3);
	// TODO: Get this from OpenVR note that ospray's units are in meters
	ospSet1f(camera, "interpupillaryDistance", 0.0635);
	ospSetVec3f(camera, "pos", (osp::vec3f&)camPos);
	ospSetVec3f(camera, "dir", (osp::vec3f&)camDir);
	ospSetVec3f(camera, "up",  (osp::vec3f&)camUp);
	ospCommit(camera);

	// Load the model w/ tinyobjloader
	tinyobj::attrib_t attrib;
	std::vector<tinyobj::shape_t> shapes;
	std::vector<tinyobj::material_t> materials;
	std::string err;
	bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, model_file.c_str(),
			nullptr, true);
	if (!err.empty()) {
		std::cerr << "Error loading model: " << err << "\n";
	}
	if (!ret) {
		return 1;
	}

	OSPModel world = ospNewModel();

	// Load all the objects into ospray
	OSPData pos_data = ospNewData(attrib.vertices.size() / 3, OSP_FLOAT3,
			attrib.vertices.data(), OSP_DATA_SHARED_BUFFER);
	ospCommit(pos_data);

	for (size_t s = 0; s < shapes.size(); ++s) {
		std::cout << "Loading mesh " << shapes[s].name
			<< ", has " << shapes[s].mesh.indices.size() << " vertices\n";
		const tinyobj::mesh_t &mesh = shapes[s].mesh;
		std::vector<int32_t> indices;
		indices.reserve(mesh.indices.size());
		for (const auto &idx : mesh.indices) {
			indices.push_back(idx.vertex_index);
		}
		OSPData idx_data = ospNewData(indices.size() / 3, OSP_INT3, indices.data());
		ospCommit(idx_data);
		OSPGeometry geom = ospNewGeometry("triangles");
		ospSetObject(geom, "vertex", pos_data);
		ospSetObject(geom, "index", idx_data);
		ospCommit(geom);
		ospAddGeometry(world, geom);
	}
	ospCommit(world);

	OSPRenderer renderer = ospNewRenderer("ao");
	ospSetObject(renderer, "model", world);
	ospSetObject(renderer, "camera", camera);
	ospSetVec3f(renderer, "bgColor", (osp::vec3f&)vec3f(0.05, 0.05, 0.05));
	ospCommit(renderer);

	OSPFrameBuffer framebuffer = ospNewFrameBuffer((osp::vec2i&)imageSize, OSP_FB_SRGBA,
			OSP_FB_COLOR | OSP_FB_ACCUM);
	ospFrameBufferClear(framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM);

	bool quit = false;
	while (!quit){
		SDL_Event e;
		while (SDL_PollEvent(&e)){
			if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)){
				quit = true;
				break;
			}
		}
		ospFrameBufferClear(framebuffer, OSP_FB_COLOR);
		ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
		const uint32_t *fb = static_cast<const uint32_t*>(ospMapFrameBuffer(framebuffer, OSP_FB_COLOR));
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIN_WIDTH, WIN_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, fb);
		ospUnmapFrameBuffer(fb, framebuffer);

		glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		glBlitFramebuffer(0, 0, WIN_WIDTH, WIN_HEIGHT, 0, 0, WIN_WIDTH, WIN_HEIGHT,
				GL_COLOR_BUFFER_BIT, GL_NEAREST);

		SDL_GL_SwapWindow(win);
	}

	SDL_GL_DeleteContext(ctx);
	SDL_DestroyWindow(win);
	SDL_Quit();
	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.cactus
 */

#include "snpbridge.h"

#include "vg/vg.hpp"
#include "Variant.h"

using namespace vcflib;
using namespace vg;
using namespace std;

SNPBridge::SNPBridge() : _vg(NULL)
{
}

SNPBridge::~SNPBridge()
{
}

void SNPBridge::processGraph(VG* vg, VariantCallFile* vcf, int offset,
                            int windowSize)
{
  _vg = vg;
  _gv1.init(offset);
  _gv2.init(offset);

  Variant var1(*vcf);
  Variant var2(*vcf);
  // skip to first variant after offset
  for (int vcfPos = -1; vcfPos < offset; vcfPos = var1.position)
  {
    if (!vcf->getNextVariant(var1))
    {
      // empty file
      cerr << "No variants found in VCF" << endl;
      return;
    }
  }
  _gv1.loadVariant(vg, var1);

  int graphLen = vgRefLength(var1);
  // used for detecting overlaps (a long deletion for example can
  // overlap many subsequent variants..)
  int lastRefPos = -1;

  for (; vcf->getNextVariant(var2); swap(var1, var2), swap(_gv1, _gv2))
  {
    if (var2.position >= offset + graphLen)
    {
      // stop after end of vg
      break;
    }

    _gv2.loadVariant(vg, var2);

    if (var2.position - (var1.position + var1.alleles[0].length() - 1) >
        windowSize)
    {
      // skip because further than window size
      continue;
    }

#ifdef DEBUG
    cerr << "\nv1 " << _gv1 << endl << "v2 " << _gv2 << endl;
#endif

    lastRefPos = max(lastRefPos, (int)(var1.position + var1.alleles[0].size()));
    if (var2.position < lastRefPos)
    {
      cerr << "Skipping adjacent variants at " << var1.position << " and "
           << var2.position
           << " because they overlap (each other or previous variant)" << endl;
      continue;
    }

    computeLinkCounts(var1, var2);

    for (int a1 = 1; a1 < var1.alleles.size(); ++a1)
    {
      for (int a2 = 1; a2 < var2.alleles.size(); ++a2)
      {
        // note can probably get what we need by calling once instead
        // of in loop....
        Phase phase = phaseRelation(var1, a1, var2, a2);

        if (phase == GT_AND)
        {
          makeBridge(a1, a2);
          // we can get away with breaking here (and below) because results
          // mutually exclusive (see simplifying assumption in
          // phaseRelation()).  So as soon as we see a GT_AND or
          // GT_XOR, then everything else must be GT_OTHER
          break;
        }
        else if (phase == GT_XOR)
        {
          makeBridge(a1, 0);
          break;
        }
        else
        {
#ifdef DEBUG
          cerr << a1 << " OTHER " << a2 << " detected at "
               << _gv1.getVariant().position << " ";
          for (int i = 0; i < _linkCounts.size(); ++i)
          {
            cerr << "(";
            for (int j = 0; j < _linkCounts[i].size(); ++j)
            {
              cerr << _linkCounts[i][j] << ",";
            }
            cerr << ") ";
          }
          cerr << endl;
#endif
        }
      }
    }
  }
}

void SNPBridge::makeBridge(int allele1, int allele2)
{
#ifdef DEBUG
  cerr << allele1 << " UNC " << allele2 << " detected at "
       << _gv1.getVariant().position << " ";
  for (int i = 0; i < _linkCounts.size(); ++i)
  {
     cerr << "(";
     for (int j = 0; j < _linkCounts[i].size(); ++j)
     {
       cerr << _linkCounts[i][j] << ",";
     }
     cerr << ") ";
  }
  cerr << endl;
#endif

  Node* node1 = _gv1.getGraphAllele(allele1).back();
  Node* node2 = _gv2.getGraphAllele(allele2).front();

  // note we don't use references here because they get altered by
  // calls to create and destroy.
  vector<pair<int64_t, bool> > outEdges1 = _vg->edges_on_end[node1->id()];
  vector<pair<int64_t, bool> > inEdges2 = _vg->edges_on_start[node2->id()];

  // make sure there's no other way out of node1 but the
  // new bridge that we'll add
  for (auto p : outEdges1)
  {
#ifdef DEBUG
    cerr << "destroy1 " << node1->id() << " " << true << ", " << p.first << " " << p.second << endl;
#endif
    Edge* edge = _vg->get_edge(NodeSide(node1->id(), true),
                               NodeSide(p.first, p.second));
    assert(edge != NULL);
    _vg->destroy_edge(edge);
  }

  // if dealting with an alt-alt case, make sure no other
  // way into second alt than the new bridge we'll add
  // (for alt-ref case, just delete any edge from prev alt)
  if (allele2 != 0)
  {
    for (auto p : inEdges2)
    {
#ifdef DEBUG
      cerr << "destroy2 " << p.first << " " << !p.second << ", " << node2->id() << " " << false << endl;
#endif
      Edge* edge = _vg->get_edge(NodeSide(p.first, !p.second),
                                 NodeSide(node2->id(), false));
      if (p.first == node1->id())
      {
        // should have been deleted above
        assert(edge == NULL);
      }
      else
      {
        assert(edge != NULL);
        _vg->destroy_edge(edge);
      }
    }
  }

  // find the path between the two variant alleles along the
  // reference.  since we only deal with consecutive variants,
  // it's sufficient to stick this path between
  list<Node*> refPath;
  _gv1.getReferencePathTo(_gv2, refPath);

  // if there's no path, we assume the variants are directly adjacent
  // and just stick and edge between them
  if (refPath.empty())
  {
    _vg->create_edge(node1, node2, false, false);
#ifdef DEBUG
    cerr << "create " << node1->id() << ", " << node2->id() << endl;
#endif
  }
  // otherwise, make a copy of ref path and stick that in between
  else
  {
    Node* prev = node1;
    for (auto refNode : refPath)
    {
      Node* cpyNode = _vg->create_node(refNode->sequence());
      _vg->create_edge(prev, cpyNode, false, false);
#ifdef DEBUG
      cerr << "create " << cpyNode->id() << endl;
      cerr << "create " << prev->id() << " -> " << cpyNode->id() << endl;
#endif
      prev = cpyNode;
    }
    _vg->create_edge(prev, node2, false, false);
#ifdef DEBUG
    cerr << "create " << prev->id() << ", " << node2->id() << endl;
#endif
  }
}

SNPBridge::Phase SNPBridge::phaseRelation(Variant& v1, int allele1,
                                        Variant& v2, int allele2) const
{
  // this is where we could take into account allele
  // frequencies to, for example, ignore really rare alleles.
  // But for now, we only do an all or nothing -- ie
  // the variants are alt-alt only if there isn't a single sample
  // saying otherwise.

  // total number of haplos with a1 that also have a2
  int toAllele2 = _linkCounts[allele1][allele2];;
  // total number of haplos with a1 that go to ref
  int toRef = _linkCounts[allele1][0];
  // total number of implied haplotypes that contain allele1
  int total = 0;
  for (int i = 0; i < v2.alleles.size(); ++i)
  {
    total += _linkCounts[allele1][i];
  }

  if (total < 1)
  {
    cerr << "Alternate allele " << allele1 << " never seen in GT for "
         << "variant " << v1 << endl;
    // the best we can do is cut path to next alternate.
    // though really we want to remove such variants
    // entirely
    return GT_XOR;
  }

  // so exclusively to allele 2 will be a GT_AND
  else if (toAllele2 == total)
  {
    return GT_AND;
  }
  // and exclusive to ref with be a GT_XOR
  // (Note a simplifiying assumption here in the
  //  presence of multiple alts.  Don't consider
  //  cases like never goes to alt2 but can go
  //  to alt1 or reference)
  else if (toRef == total)
  {
    return GT_XOR;
  }

  return GT_OTHER;
}

void SNPBridge::computeLinkCounts(Variant& v1, Variant& v2)
{
  // make our matrix and set to 0
  initLinkCounts(v1, v2);

  assert(!v1.alleles.empty() && !v2.alleles.empty());

  for (auto& sample : v1.sampleNames)
  {
    // treat missing GT information in one variant with respect
    // to the other as a warning. But count all possible links
    // once so it will never get phased.
    if (v2.samples.find(sample) == v2.samples.end())
    {
      cerr << "Warning: Sample " << sample << " not found in variant " << v2
           << ". Assuming unphased" << endl;
      for (auto& i : _linkCounts)
      {
        for (auto& j : i)
        {
          ++j;
        }
      }

      continue;
    }

    // parse out GT info for sample (it'll look like 0|1 etc.)
    string& gt1 = v1.samples[sample]["GT"].front();
    string& gt2 = v2.samples[sample]["GT"].front();
    vector<string> gtspec1 = split(gt1, "|");
    vector<string> gtspec2 = split(gt2, "|");

    // don't expect this but check in case
    if (gtspec1.size() != gtspec2.size())
    {
      stringstream ss;
      ss << "Sample " << sample << "has different ploidy in "
         << v1 << " and " << v2 << ". This is not supported";
      throw runtime_error(ss.str());
    }

    // so if the GT info looks like 0|1 1|0 2|1 etc.  we have
    // two "chromosomes", and iterate each.  we count a link
    // looking at the two variants, and recording what we see
    // at the same chromosome at the same sample.
    for (int chrom = 0; chrom < gtspec1.size(); ++chrom)
    {
      // treat . as wildcard
      if (gtspec1[chrom] == "." && gtspec2[chrom] == ".")
      {
        // two .'s mean we see everything
        for (int g1 = 0; g1 < v1.alleles.size(); ++g1)
        {
          for (int g2 = 0; g2 < v2.alleles.size(); ++g2)
          {
            ++_linkCounts[g1][g2];
          }
        }
      }
      else if (gtspec1[chrom] == ".")
      {
        // g1 == . means we see all combindations of g1 with
        // given value of g2
        int g2;
        convert(gtspec2[chrom], g2);
        for (int g1 = 0; g1 < v1.alleles.size(); ++g1)
        {
          ++_linkCounts[g1][g2];
        }
      }
      else if (gtspec2[chrom] == ".")
      {
        // g2 == . means we see all combinations of g2 with
        // given value of g1
        int g1;
        convert(gtspec1[chrom], g1);
        for (int g2 = 0; g2 < v2.alleles.size(); ++g2)
        {
          ++_linkCounts[g1][g2];
        }
      }
      else
      {
        // normal case.  update the link count for the indexes
        // found on the give allele.  Example
        // Sample NA12878 has GT 0|1 for var1 and 0|0 for var2
        // then we update _linkCounts[0][1] + 1 (when chrom = 0)
        // and _linkCounots[0][0] + 1 (when chrom = 1)
        int g1, g2;
        convert(gtspec1[chrom], g1);
        convert(gtspec2[chrom], g2);
        ++_linkCounts[g1][g2];
      }
    }
  }
}

void SNPBridge::initLinkCounts(Variant& v1,
                              Variant& v2)
{
  // set _linkCounts to 0 and make sure it's at least
  // big enough to hold our alleles
  for (int i = 0; i < v1.alleles.size(); ++i)
  {
    if (_linkCounts.size() < v1.alleles.size())
    {
      _linkCounts.push_back(vector<int>(v2.alleles.size(), 0));
    }
    else
    {
      if (_linkCounts[i].size() < v2.alleles.size())
      {
        _linkCounts[i].resize(v2.alleles.size());
      }
      _linkCounts[i].assign(v2.alleles.size(), 0);
    }
  }
}

int SNPBridge::vgRefLength(Variant& var) const
{
  // duplicating some code from the built in traversal of graphvariant,
  // but it's nice to have path length at outset to make scope checking
  // simpler (to relax assumption that vg contains whole vcf).
  if (_vg->paths.has_path(var.sequenceName) == false)
  {
    stringstream ss;
    ss << "Unable to find path for " << var.sequenceName << " in vg file";
    throw runtime_error(ss.str());
  }
  int len = 0;
  list<Mapping>& path = _vg->paths.get_path(var.sequenceName);
  for (auto& mapping : path)
  {
    if (mapping.is_reverse() == true)
    {
      throw(runtime_error("Reverse Mapping not supported"));
    }
    if (mapping.edit_size() > 1 || (
          mapping.edit_size() == 1 && mapping.edit(0).from_length() !=
          mapping.edit(0).to_length()))
    {
      stringstream ss;
      ss << pb2json(mapping) << ": Only mappings with a single trvial edit"
         << " supported in ref path";
      throw runtime_error(ss.str());
    }
    len += _vg->get_node(mapping.position().node_id())->sequence().length();
  }
  return len;
}
<commit_msg>change overlap logic yet again.  need to skip overlaps before loading as they can fail a sanity check<commit_after>/*
 * Copyright (C) 2015 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.cactus
 */

#include "snpbridge.h"

#include "vg/vg.hpp"
#include "Variant.h"

using namespace vcflib;
using namespace vg;
using namespace std;

SNPBridge::SNPBridge() : _vg(NULL)
{
}

SNPBridge::~SNPBridge()
{
}

void SNPBridge::processGraph(VG* vg, VariantCallFile* vcf, int offset,
                            int windowSize)
{
  _vg = vg;
  _gv1.init(offset);
  _gv2.init(offset);

  Variant var1(*vcf);
  Variant var2(*vcf);
  // skip to first variant after offset
  for (int vcfPos = -1; vcfPos < offset; vcfPos = var1.position)
  {
    if (!vcf->getNextVariant(var1))
    {
      // empty file
      cerr << "No variants found in VCF" << endl;
      return;
    }
  }
  _gv1.loadVariant(vg, var1);

  int graphLen = vgRefLength(var1);

  for (; vcf->getNextVariant(var2); swap(var1, var2), swap(_gv1, _gv2))
  {
    // skip ahead until we're not overlapping
    bool breakOut = false;
    while (!breakOut && var2.position < var1.position + var1.alleles[0].size())
    {
      cerr << "Skipping variant at " << var2.position << " because it "
           << "overlaps previous variant at position " << var1.position << endl;
      breakOut = !vcf->getNextVariant(var2);
    }
    if (breakOut)
    {
      break;
    }

    if (var2.position >= offset + graphLen)
    {
      // stop after end of vg
      break;
    }

    _gv2.loadVariant(vg, var2);

    if (var2.position - (var1.position + var1.alleles[0].length() - 1) >
        windowSize)
    {
      // skip because further than window size
      continue;
    }

#ifdef DEBUG
    cerr << "\nv1 " << _gv1 << endl << "v2 " << _gv2 << endl;
#endif

    computeLinkCounts(var1, var2);

    for (int a1 = 1; a1 < var1.alleles.size(); ++a1)
    {
      for (int a2 = 1; a2 < var2.alleles.size(); ++a2)
      {
        // note can probably get what we need by calling once instead
        // of in loop....
        Phase phase = phaseRelation(var1, a1, var2, a2);

        if (phase == GT_AND)
        {
          makeBridge(a1, a2);
          // we can get away with breaking here (and below) because results
          // mutually exclusive (see simplifying assumption in
          // phaseRelation()).  So as soon as we see a GT_AND or
          // GT_XOR, then everything else must be GT_OTHER
          break;
        }
        else if (phase == GT_XOR)
        {
          makeBridge(a1, 0);
          break;
        }
        else
        {
#ifdef DEBUG
          cerr << a1 << " OTHER " << a2 << " detected at "
               << _gv1.getVariant().position << " ";
          for (int i = 0; i < _linkCounts.size(); ++i)
          {
            cerr << "(";
            for (int j = 0; j < _linkCounts[i].size(); ++j)
            {
              cerr << _linkCounts[i][j] << ",";
            }
            cerr << ") ";
          }
          cerr << endl;
#endif
        }
      }
    }
  }
}

void SNPBridge::makeBridge(int allele1, int allele2)
{
#ifdef DEBUG
  cerr << allele1 << " UNC " << allele2 << " detected at "
       << _gv1.getVariant().position << " ";
  for (int i = 0; i < _linkCounts.size(); ++i)
  {
     cerr << "(";
     for (int j = 0; j < _linkCounts[i].size(); ++j)
     {
       cerr << _linkCounts[i][j] << ",";
     }
     cerr << ") ";
  }
  cerr << endl;
#endif

  Node* node1 = _gv1.getGraphAllele(allele1).back();
  Node* node2 = _gv2.getGraphAllele(allele2).front();

  // note we don't use references here because they get altered by
  // calls to create and destroy.
  vector<pair<int64_t, bool> > outEdges1 = _vg->edges_on_end[node1->id()];
  vector<pair<int64_t, bool> > inEdges2 = _vg->edges_on_start[node2->id()];

  // make sure there's no other way out of node1 but the
  // new bridge that we'll add
  for (auto p : outEdges1)
  {
#ifdef DEBUG
    cerr << "destroy1 " << node1->id() << " " << true << ", " << p.first << " " << p.second << endl;
#endif
    Edge* edge = _vg->get_edge(NodeSide(node1->id(), true),
                               NodeSide(p.first, p.second));
    assert(edge != NULL);
    _vg->destroy_edge(edge);
  }

  // if dealting with an alt-alt case, make sure no other
  // way into second alt than the new bridge we'll add
  // (for alt-ref case, just delete any edge from prev alt)
  if (allele2 != 0)
  {
    for (auto p : inEdges2)
    {
#ifdef DEBUG
      cerr << "destroy2 " << p.first << " " << !p.second << ", " << node2->id() << " " << false << endl;
#endif
      Edge* edge = _vg->get_edge(NodeSide(p.first, !p.second),
                                 NodeSide(node2->id(), false));
      if (p.first == node1->id())
      {
        // should have been deleted above
        assert(edge == NULL);
      }
      else
      {
        assert(edge != NULL);
        _vg->destroy_edge(edge);
      }
    }
  }

  // find the path between the two variant alleles along the
  // reference.  since we only deal with consecutive variants,
  // it's sufficient to stick this path between
  list<Node*> refPath;
  _gv1.getReferencePathTo(_gv2, refPath);

  // if there's no path, we assume the variants are directly adjacent
  // and just stick and edge between them
  if (refPath.empty())
  {
    _vg->create_edge(node1, node2, false, false);
#ifdef DEBUG
    cerr << "create " << node1->id() << ", " << node2->id() << endl;
#endif
  }
  // otherwise, make a copy of ref path and stick that in between
  else
  {
    Node* prev = node1;
    for (auto refNode : refPath)
    {
      Node* cpyNode = _vg->create_node(refNode->sequence());
      _vg->create_edge(prev, cpyNode, false, false);
#ifdef DEBUG
      cerr << "create " << cpyNode->id() << endl;
      cerr << "create " << prev->id() << " -> " << cpyNode->id() << endl;
#endif
      prev = cpyNode;
    }
    _vg->create_edge(prev, node2, false, false);
#ifdef DEBUG
    cerr << "create " << prev->id() << ", " << node2->id() << endl;
#endif
  }
}

SNPBridge::Phase SNPBridge::phaseRelation(Variant& v1, int allele1,
                                        Variant& v2, int allele2) const
{
  // this is where we could take into account allele
  // frequencies to, for example, ignore really rare alleles.
  // But for now, we only do an all or nothing -- ie
  // the variants are alt-alt only if there isn't a single sample
  // saying otherwise.

  // total number of haplos with a1 that also have a2
  int toAllele2 = _linkCounts[allele1][allele2];;
  // total number of haplos with a1 that go to ref
  int toRef = _linkCounts[allele1][0];
  // total number of implied haplotypes that contain allele1
  int total = 0;
  for (int i = 0; i < v2.alleles.size(); ++i)
  {
    total += _linkCounts[allele1][i];
  }

  if (total < 1)
  {
    cerr << "Alternate allele " << allele1 << " never seen in GT for "
         << "variant " << v1 << endl;
    // the best we can do is cut path to next alternate.
    // though really we want to remove such variants
    // entirely
    return GT_XOR;
  }

  // so exclusively to allele 2 will be a GT_AND
  else if (toAllele2 == total)
  {
    return GT_AND;
  }
  // and exclusive to ref with be a GT_XOR
  // (Note a simplifiying assumption here in the
  //  presence of multiple alts.  Don't consider
  //  cases like never goes to alt2 but can go
  //  to alt1 or reference)
  else if (toRef == total)
  {
    return GT_XOR;
  }

  return GT_OTHER;
}

void SNPBridge::computeLinkCounts(Variant& v1, Variant& v2)
{
  // make our matrix and set to 0
  initLinkCounts(v1, v2);

  assert(!v1.alleles.empty() && !v2.alleles.empty());

  for (auto& sample : v1.sampleNames)
  {
    // treat missing GT information in one variant with respect
    // to the other as a warning. But count all possible links
    // once so it will never get phased.
    if (v2.samples.find(sample) == v2.samples.end())
    {
      cerr << "Warning: Sample " << sample << " not found in variant " << v2
           << ". Assuming unphased" << endl;
      for (auto& i : _linkCounts)
      {
        for (auto& j : i)
        {
          ++j;
        }
      }

      continue;
    }

    // parse out GT info for sample (it'll look like 0|1 etc.)
    string& gt1 = v1.samples[sample]["GT"].front();
    string& gt2 = v2.samples[sample]["GT"].front();
    vector<string> gtspec1 = split(gt1, "|");
    vector<string> gtspec2 = split(gt2, "|");

    // don't expect this but check in case
    if (gtspec1.size() != gtspec2.size())
    {
      stringstream ss;
      ss << "Sample " << sample << "has different ploidy in "
         << v1 << " and " << v2 << ". This is not supported";
      throw runtime_error(ss.str());
    }

    // so if the GT info looks like 0|1 1|0 2|1 etc.  we have
    // two "chromosomes", and iterate each.  we count a link
    // looking at the two variants, and recording what we see
    // at the same chromosome at the same sample.
    for (int chrom = 0; chrom < gtspec1.size(); ++chrom)
    {
      // treat . as wildcard
      if (gtspec1[chrom] == "." && gtspec2[chrom] == ".")
      {
        // two .'s mean we see everything
        for (int g1 = 0; g1 < v1.alleles.size(); ++g1)
        {
          for (int g2 = 0; g2 < v2.alleles.size(); ++g2)
          {
            ++_linkCounts[g1][g2];
          }
        }
      }
      else if (gtspec1[chrom] == ".")
      {
        // g1 == . means we see all combindations of g1 with
        // given value of g2
        int g2;
        convert(gtspec2[chrom], g2);
        for (int g1 = 0; g1 < v1.alleles.size(); ++g1)
        {
          ++_linkCounts[g1][g2];
        }
      }
      else if (gtspec2[chrom] == ".")
      {
        // g2 == . means we see all combinations of g2 with
        // given value of g1
        int g1;
        convert(gtspec1[chrom], g1);
        for (int g2 = 0; g2 < v2.alleles.size(); ++g2)
        {
          ++_linkCounts[g1][g2];
        }
      }
      else
      {
        // normal case.  update the link count for the indexes
        // found on the give allele.  Example
        // Sample NA12878 has GT 0|1 for var1 and 0|0 for var2
        // then we update _linkCounts[0][1] + 1 (when chrom = 0)
        // and _linkCounots[0][0] + 1 (when chrom = 1)
        int g1, g2;
        convert(gtspec1[chrom], g1);
        convert(gtspec2[chrom], g2);
        ++_linkCounts[g1][g2];
      }
    }
  }
}

void SNPBridge::initLinkCounts(Variant& v1,
                              Variant& v2)
{
  // set _linkCounts to 0 and make sure it's at least
  // big enough to hold our alleles
  for (int i = 0; i < v1.alleles.size(); ++i)
  {
    if (_linkCounts.size() < v1.alleles.size())
    {
      _linkCounts.push_back(vector<int>(v2.alleles.size(), 0));
    }
    else
    {
      if (_linkCounts[i].size() < v2.alleles.size())
      {
        _linkCounts[i].resize(v2.alleles.size());
      }
      _linkCounts[i].assign(v2.alleles.size(), 0);
    }
  }
}

int SNPBridge::vgRefLength(Variant& var) const
{
  // duplicating some code from the built in traversal of graphvariant,
  // but it's nice to have path length at outset to make scope checking
  // simpler (to relax assumption that vg contains whole vcf).
  if (_vg->paths.has_path(var.sequenceName) == false)
  {
    stringstream ss;
    ss << "Unable to find path for " << var.sequenceName << " in vg file";
    throw runtime_error(ss.str());
  }
  int len = 0;
  list<Mapping>& path = _vg->paths.get_path(var.sequenceName);
  for (auto& mapping : path)
  {
    if (mapping.is_reverse() == true)
    {
      throw(runtime_error("Reverse Mapping not supported"));
    }
    if (mapping.edit_size() > 1 || (
          mapping.edit_size() == 1 && mapping.edit(0).from_length() !=
          mapping.edit(0).to_length()))
    {
      stringstream ss;
      ss << pb2json(mapping) << ": Only mappings with a single trvial edit"
         << " supported in ref path";
      throw runtime_error(ss.str());
    }
    len += _vg->get_node(mapping.position().node_id())->sequence().length();
  }
  return len;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: javaedit.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2007-10-22 15:19:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SW_JAVAEDIT_HXX
#define _SW_JAVAEDIT_HXX

// include ---------------------------------------------------------------

#ifndef _SVX_STDDLG_HXX //autogen
#include <svx/stddlg.hxx>
#endif

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_SVMEDIT_HXX //autogen
#include <svtools/svmedit.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif

class SwWrtShell;
class SwFldMgr;
class SwScriptField;

namespace sfx2 { class FileDialogHelper; }

// class SwJavaEditDialog -------------------------------------------------

class SwJavaEditDialog : public SvxStandardDialog
{
private:
    FixedText           aTypeFT;
    Edit                aTypeED;
    RadioButton         aUrlRB;
    RadioButton         aEditRB;
    PushButton          aUrlPB;
    Edit                aUrlED;
    MultiLineEdit       aEditED;
    FixedLine           aPostItFL;

    OKButton            aOKBtn;
    CancelButton        aCancelBtn;
    ImageButton         aPrevBtn;
    ImageButton         aNextBtn;
    HelpButton          aHelpBtn;

    String              aText;
    String              aType;

    BOOL                bNew;
    BOOL                bIsUrl;

    SwScriptField*          pFld;
    SwFldMgr*               pMgr;
    SwWrtShell*             pSh;
    sfx2::FileDialogHelper* pFileDlg;
    Window*                 pOldDefDlgParent;

    DECL_LINK( OKHdl, Button* );
    DECL_LINK( PrevHdl, Button* );
    DECL_LINK( NextHdl, Button* );
    DECL_LINK( RadioButtonHdl, RadioButton* pBtn );
    DECL_LINK( InsertFileHdl, PushButton * );
    DECL_LINK( DlgClosedHdl, sfx2::FileDialogHelper * );

    virtual void    Apply();

    void            CheckTravel();
    void            SetFld();

    using Window::GetText;
    using Window::GetType;

public:
    SwJavaEditDialog(Window* pParent, SwWrtShell* pWrtSh);
    ~SwJavaEditDialog();

    String              GetText() { return aText; }

    String              GetType() { return aType; }

    BOOL                IsUrl() { return bIsUrl; }
    BOOL                IsNew() { return bNew; }
    BOOL                IsUpdate();
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.8.216); FILE MERGED 2008/04/01 15:59:14 thb 1.8.216.2: #i85898# Stripping all external header guards 2008/03/31 16:58:33 rt 1.8.216.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: javaedit.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SW_JAVAEDIT_HXX
#define _SW_JAVAEDIT_HXX

// include ---------------------------------------------------------------

#include <svx/stddlg.hxx>

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_SVMEDIT_HXX //autogen
#include <svtools/svmedit.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif

class SwWrtShell;
class SwFldMgr;
class SwScriptField;

namespace sfx2 { class FileDialogHelper; }

// class SwJavaEditDialog -------------------------------------------------

class SwJavaEditDialog : public SvxStandardDialog
{
private:
    FixedText           aTypeFT;
    Edit                aTypeED;
    RadioButton         aUrlRB;
    RadioButton         aEditRB;
    PushButton          aUrlPB;
    Edit                aUrlED;
    MultiLineEdit       aEditED;
    FixedLine           aPostItFL;

    OKButton            aOKBtn;
    CancelButton        aCancelBtn;
    ImageButton         aPrevBtn;
    ImageButton         aNextBtn;
    HelpButton          aHelpBtn;

    String              aText;
    String              aType;

    BOOL                bNew;
    BOOL                bIsUrl;

    SwScriptField*          pFld;
    SwFldMgr*               pMgr;
    SwWrtShell*             pSh;
    sfx2::FileDialogHelper* pFileDlg;
    Window*                 pOldDefDlgParent;

    DECL_LINK( OKHdl, Button* );
    DECL_LINK( PrevHdl, Button* );
    DECL_LINK( NextHdl, Button* );
    DECL_LINK( RadioButtonHdl, RadioButton* pBtn );
    DECL_LINK( InsertFileHdl, PushButton * );
    DECL_LINK( DlgClosedHdl, sfx2::FileDialogHelper * );

    virtual void    Apply();

    void            CheckTravel();
    void            SetFld();

    using Window::GetText;
    using Window::GetType;

public:
    SwJavaEditDialog(Window* pParent, SwWrtShell* pWrtSh);
    ~SwJavaEditDialog();

    String              GetText() { return aText; }

    String              GetType() { return aType; }

    BOOL                IsUrl() { return bIsUrl; }
    BOOL                IsNew() { return bNew; }
    BOOL                IsUpdate();
};

#endif

<|endoftext|>


<commit_before>//! \file main.cpp

#include <fstream>
#include <iostream>
#include <string>

#include "Article.h"
#include "ToGraphvizWriter.h"
#include "WikiWalker.h"
#include "version.h"

#include "config.h"

using CmdOpt = WikiWalker::CommandLineParserBase::CommandLineOptions;

//! limit for printing article links / contents
const int printLimit = 10;

int main(int argc, char** argv)
{
#if defined(WW_USE_BOOST_PO)
  WikiWalker::BoostPoCommandLineParser cmdp;
#elif defined(WW_USE_GETOPT)
  WikiWalker::GetoptCommandLineParser cmdp;
#endif

  try {
    cmdp.parse(argc, argv);
  } catch(std::exception& e) {
    std::cerr << std::endl << e.what() << std::endl;
    cmdp.printHelp();
    return -1;
  }

  if(cmdp.hasSet(CmdOpt::Version)) {
    std::cout << "WikiWalker, version " << _WW_VERSION << std::endl;
    return 0;
  }

  if(cmdp.hasSet(CmdOpt::Help)) {
    cmdp.printHelp();
    return 0;
  }

  bool isUrlSet       = cmdp.hasSet(CmdOpt::URL);
  bool isCacheSet     = cmdp.hasSet(CmdOpt::JsonCache);
  bool isDotSet       = cmdp.hasSet(CmdOpt::DotOut);
  bool isDeepSet      = cmdp.hasSet(CmdOpt::FetchDeep);
  bool validRunConfig = isUrlSet || (isDotSet && isCacheSet);

  if(!validRunConfig) {
    std::cerr << "Must either specify at least URL, "
              << "or dot and cache file." << std::endl;
    cmdp.printHelp();
    return 1;
  }

  if(isUrlSet && isDeepSet && !isCacheSet) {
    std::cerr << "Please specify a cache file when using \"deep\" option"
              << std::endl;
    cmdp.printHelp();
    return 1;
  }

  bool read_failed = false;
  WikiWalker::WikiWalker w;

  if(isCacheSet) {
    try {
      std::string cachefile = cmdp.getValue(CmdOpt::JsonCache);
      w.readCache(cachefile);
    } catch(std::exception& e) {
      std::cout << e.what() << std::endl;
      read_failed = true;
    }
  }

  if(isUrlSet) {
    try {
      std::string url = cmdp.getValue(CmdOpt::URL);
      w.startWalking(url);
    } catch(std::exception& e) {
      std::cout << "Error: " << e.what() << std::endl;
      return -1;
    }
  }

  if(isCacheSet) {
    std::string cachefile = cmdp.getValue(CmdOpt::JsonCache);
    if(read_failed) {
      cachefile.append("_");
      std::cout << "Reading from cache failed, write to " << cachefile
                << std::endl;
    }
    try {
      w.writeCache(cachefile);
    } catch(std::exception& e) {
      std::cout << "Error: " << e.what() << std::endl;
    }
  }

  if(isDotSet) {
    const WikiWalker::ArticleCollection& ac = w.getCollection();
    std::string outfile                     = cmdp.getValue(CmdOpt::DotOut);
    WikiWalker::ToGraphvizWriter tgw;
    std::ofstream file(outfile, std::ios::trunc | std::ios::out);

    if(file.fail()) {
      std::cerr << "Error opening dot out file for writing" << std::endl;
    } else {
      tgw.output(ac, file);
      file.flush();

      if(file.bad() || file.fail()) {
        std::cerr << "Error during writing dot out file." << std::endl;
      }

      file.close();
    }
  }

  size_t numArt = w.getCollection().getNumAnalyzedArticles();
  if(numArt > 10) {
    std::cout << "There are " << numArt << " analyzed articles."
              << " Not printing them. (Limit: " << printLimit << ")."
              << std::endl;
  } else {
    for(auto& a : w.getCollection()) {
      auto& art = a.second;
      if(art->isAnalyzed()) {
        std::cout << "Article " << a.first << " has " << art->getNumLinks()
                  << " links" << std::endl;
      }
    }
  }

  return 0;
}
<commit_msg>Output when article is missing/invalid<commit_after>//! \file main.cpp

#include <fstream>
#include <iostream>
#include <string>

#include "Article.h"
#include "ToGraphvizWriter.h"
#include "WikiWalker.h"
#include "version.h"

#include "config.h"

using CmdOpt = WikiWalker::CommandLineParserBase::CommandLineOptions;

//! limit for printing article links / contents
const int printLimit = 10;

int main(int argc, char** argv)
{
#if defined(WW_USE_BOOST_PO)
  WikiWalker::BoostPoCommandLineParser cmdp;
#elif defined(WW_USE_GETOPT)
  WikiWalker::GetoptCommandLineParser cmdp;
#endif

  try {
    cmdp.parse(argc, argv);
  } catch(std::exception& e) {
    std::cerr << std::endl << e.what() << std::endl;
    cmdp.printHelp();
    return -1;
  }

  if(cmdp.hasSet(CmdOpt::Version)) {
    std::cout << "WikiWalker, version " << _WW_VERSION << std::endl;
    return 0;
  }

  if(cmdp.hasSet(CmdOpt::Help)) {
    cmdp.printHelp();
    return 0;
  }

  bool isUrlSet       = cmdp.hasSet(CmdOpt::URL);
  bool isCacheSet     = cmdp.hasSet(CmdOpt::JsonCache);
  bool isDotSet       = cmdp.hasSet(CmdOpt::DotOut);
  bool isDeepSet      = cmdp.hasSet(CmdOpt::FetchDeep);
  bool validRunConfig = isUrlSet || (isDotSet && isCacheSet);

  if(!validRunConfig) {
    std::cerr << "Must either specify at least URL, "
              << "or dot and cache file." << std::endl;
    cmdp.printHelp();
    return 1;
  }

  if(isUrlSet && isDeepSet && !isCacheSet) {
    std::cerr << "Please specify a cache file when using \"deep\" option"
              << std::endl;
    cmdp.printHelp();
    return 1;
  }

  bool read_failed = false;
  WikiWalker::WikiWalker w;

  if(isCacheSet) {
    try {
      std::string cachefile = cmdp.getValue(CmdOpt::JsonCache);
      w.readCache(cachefile);
    } catch(std::exception& e) {
      std::cout << e.what() << std::endl;
      read_failed = true;
    }
  }

  if(isUrlSet) {
    try {
      std::string url = cmdp.getValue(CmdOpt::URL);
      w.startWalking(url);
    } catch(std::exception& e) {
      std::cout << "Error: " << e.what() << std::endl;
      return -1;
    }
  }

  if(isCacheSet) {
    std::string cachefile = cmdp.getValue(CmdOpt::JsonCache);
    if(read_failed) {
      cachefile.append("_");
      std::cout << "Reading from cache failed, write to " << cachefile
                << std::endl;
    }
    try {
      w.writeCache(cachefile);
    } catch(std::exception& e) {
      std::cout << "Error: " << e.what() << std::endl;
    }
  }

  if(isDotSet) {
    const WikiWalker::ArticleCollection& ac = w.getCollection();
    std::string outfile                     = cmdp.getValue(CmdOpt::DotOut);
    WikiWalker::ToGraphvizWriter tgw;
    std::ofstream file(outfile, std::ios::trunc | std::ios::out);

    if(file.fail()) {
      std::cerr << "Error opening dot out file for writing" << std::endl;
    } else {
      tgw.output(ac, file);
      file.flush();

      if(file.bad() || file.fail()) {
        std::cerr << "Error during writing dot out file." << std::endl;
      }

      file.close();
    }
  }

  size_t numArt = w.getCollection().getNumAnalyzedArticles();
  if(numArt > 10) {
    std::cout << "There are " << numArt << " analyzed articles."
              << " Not printing them. (Limit: " << printLimit << ")."
              << std::endl;
  } else {
    for(auto& a : w.getCollection()) {
      auto& art = a.second;
      if(art->isMarked()) {
        std::cout << "Article " << a.first << " is invalid or doesn't exist"
                  << std::endl;
      } else if(art->isAnalyzed()) {
        std::cout << "Article " << a.first << " has " << art->getNumLinks()
                  << " links" << std::endl;
      }
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef CONST_H
#define CONST_H

using namespace std;

const int WORD_SIZE = 8;
const int ADDR_SIZE = 4;
const int RAM_SIZE = 15;

// Miliseconds between cycles (if automatic)
const int FQ = 300;

const int NUM_OF_INSTRUCTIONS = 8;

#endif<commit_msg>a tad slower clock for more natural flow<commit_after>#ifndef CONST_H
#define CONST_H

using namespace std;

const int WORD_SIZE = 8;
const int ADDR_SIZE = 4;
const int RAM_SIZE = 15;

// Miliseconds between cycles (if automatic)
const int FQ = 333;

const int NUM_OF_INSTRUCTIONS = 8;

#endif
<|endoftext|>