<commit_before>// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>

#include "letter_coordinates.hpp"

using namespace std;

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <glfw3.h>
GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

#include <common/shader.hpp>
//#include <common/texture.hpp>
#include <common/controls.hpp>

/* Constants */
#define STD_RADIUS 0.1

/* Forward declarations */
GLfloat getXVector (const double aPhi, const double aTheta);
GLfloat getYVector (const double aPhi, const double aTheta);
GLfloat getZVector (const double aTheta);

/* Obtained from http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html */
void Tokenize(const string& str,
				vector<string>& tokens,
				const string& delimiters)
{
	// Skip delimiters at beginning.
	string::size_type lastPos = str.find_first_not_of(delimiters, 0);
	// Find first "non-delimiter".
	string::size_type pos     = str.find_first_of(delimiters, lastPos);

	while (string::npos != pos || string::npos != lastPos)
	{
		// Found a token, add it to the vector.
		tokens.push_back(str.substr(lastPos, pos - lastPos));
		// Skip delimiters.  Note the "not_of"
		lastPos = str.find_first_not_of(delimiters, pos);
		// Find next "non-delimiter"
		pos = str.find_first_of(delimiters, lastPos);
	}
}

/*
 * Standard convention is:
 * x = r * sin THETA * cos PHI
 * y = r * sin THETA * sin PHI
 * z = r * cos THETA
 *
 * Here we set r = 0.1 and swap axes for OpenGL such that:
 * Std ---> OpenGL
 *  x  --->   z
 *  y  --->   x
 *  z  --->   y
 */

void getVectors(GLfloat &aDeltaX, GLfloat &aDeltaY, GLfloat &aDeltaZ, const double aPhi, const double aTheta)
{
	aDeltaX = getYVector(aPhi, aTheta);
	aDeltaY = getZVector(aTheta);
	aDeltaZ = getXVector(aPhi, aTheta);
}

GLfloat getXVector (const double aPhi, const double aTheta)
{
	return STD_RADIUS * sin(aTheta) * cos(aPhi);
}

GLfloat getYVector (const double aPhi, const double aTheta)
{
	return STD_RADIUS * sin(aTheta) * sin(aPhi);
}

GLfloat getZVector (const double aTheta)
{
	return STD_RADIUS * cos(aTheta);
}

void populateSensorVertexBuffers(int aSensorIndex, const vector<string>& aMovementsPairs, GLfloat* aSensorVertexBufferData) {
	//printf("sizeof(aSensorVertexBufferData): %li\n", sizeof(aSensorVertexBufferData));
	//printf("numVertexBufferElems: %li\n", numVertexBufferElems);
	GLfloat tempCoordinates[3] = { 0.0f, 0.0f, 0.0f };
	aSensorVertexBufferData[0] = 0.0f;
	aSensorVertexBufferData[1] = 0.0f;
	aSensorVertexBufferData[2] = 0.0f;
	for (int i = 0; i < aMovementsPairs.size(); i++) {
		int j = i * 3;
		string currentMovementPair = aMovementsPairs[i];
		//cout << currentMovementPair << endl;
		char currentMovement = currentMovementPair.c_str()[aSensorIndex];
		//cout << currentMovement << endl;
		/*
		 * Spherical gesture coordinates in PHI, THETA format
		 */
		GLfloat deltaX, deltaY, deltaZ;
		if (currentMovement == '_') {
			deltaX = 0.0f;
			deltaY = 0.0f;
			deltaZ = 0.0f;
		} else {
			struct sphericalCoordinates currentCoordinates =
					letterCoordinates[currentMovement];
			getVectors(deltaX, deltaY, deltaZ,
					degreesToRadians(currentCoordinates.mPhi),
					degreesToRadians(currentCoordinates.mTheta));
		}
		//cout << "movement " << currentS1Movement << " dx: " << deltaX << " dy: " << deltaY << " dz: " << deltaZ << endl;
		tempCoordinates[0] += deltaX;
		tempCoordinates[1] += deltaY;
		tempCoordinates[2] += deltaZ;
		aSensorVertexBufferData[j + 3] = tempCoordinates[0];
		aSensorVertexBufferData[j + 4] = tempCoordinates[1];
		aSensorVertexBufferData[j + 5] = tempCoordinates[2];
		//printf("vertex[%i, %i, %i] = {%f, %f, %f}\n", j+3, j+4, j+5, tempCoordinates[0], tempCoordinates[1], tempCoordinates[2]);
	}
}

void populateSensorColorBuffers(GLfloat* aSensor0ColorBufferData, GLfloat* aSensor1ColorBufferData, int aNumVertexBufferElems)
{
	int numMovements = aNumVertexBufferElems / 3;
	int numColorIntensityJumps = numMovements - 1;
	float colorIntensityInterval = 1.0f / numColorIntensityJumps;

	GLfloat sensor0TempIntensities[3] = { 0.0f, 0.0f, 0.0f }; // R,G,B
	GLfloat sensor1TempIntensities[3] = { 0.0f, 0.0f, 0.0f }; // R,G,B

	/* Origin is colored with intensity 0.0f */
	for (int i = 0; i < 3; i++) {
		aSensor0ColorBufferData[i] = 0.0f;
		aSensor1ColorBufferData[i] = 0.0f;
	}

	for (int i = 3; i < (aNumVertexBufferElems-2); i+=3) {
		cout << "i: " << i << endl;
		sensor0TempIntensities[0] += colorIntensityInterval; // Intensify red for sensor 0
		sensor1TempIntensities[2] += colorIntensityInterval; // Intensify blue for sensor 1

		aSensor0ColorBufferData[i] = sensor0TempIntensities[0];
		aSensor0ColorBufferData[i+1] = sensor0TempIntensities[1];
		aSensor0ColorBufferData[i+2] = sensor0TempIntensities[2];

		aSensor1ColorBufferData[i] = sensor1TempIntensities[0];
		aSensor1ColorBufferData[i+1] = sensor1TempIntensities[1];
		aSensor1ColorBufferData[i+2] = sensor1TempIntensities[2];
	}
}

int main( void )
{
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		return -1;
	}

	glfwWindowHint(GLFW_SAMPLES, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

	// Open a window and create its OpenGL context
	window = glfwCreateWindow( 1280, 1024, "Gesture visualizer", NULL, NULL);
	if( window == NULL ){
		fprintf( stderr, "Failed to open GLFW window.\n" );
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	if (glewInit() != GLEW_OK) {
		fprintf(stderr, "Failed to initialize GLEW\n");
		return -1;
	}

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetCursorPos(window, 1280/2, 1024/2);

	// White background
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

	// Thick lines
	glLineWidth(3.0f);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);

	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LESS);

	// Cull triangles which normal is not towards the camera
	glEnable(GL_CULL_FACE);

	// Create and compile our GLSL program from the shaders
	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader" );

	// Get a handle for our "MVP" uniform
	GLuint MatrixID = glGetUniformLocation(programID, "MVP");

	// Get a handle for our buffers
	GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
	GLuint colorIntensityID = glGetAttribLocation(programID, "colorIntensity");
	//GLuint vertexUVID = glGetAttribLocation(programID, "vertexUV");

	// Get a handle for our "myTextureSampler" uniform
	GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");

	ifstream gestureFile;
	gestureFile.open("gesture.dat");
	if (!gestureFile.is_open()) {
		return 0;
	}

	string line;
	if (!getline(gestureFile, line)) {
		return 0;
	}

	vector<string> movementPairs;
	Tokenize(line, movementPairs, ".");

	cout << "String: " << line << endl;
	long int numVertexBufferElems = (movementPairs.size()+1) * 3; // One extra entry at the beginning for coordinate {0.0f, 0.0f, 0.0f}

	GLfloat* sensor0VertexBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor0ColorBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor1VertexBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor1ColorBufferData = new GLfloat[numVertexBufferElems];

	populateSensorVertexBuffers(0, movementPairs, sensor0VertexBufferData);
	populateSensorVertexBuffers(1, movementPairs, sensor1VertexBufferData);
	populateSensorColorBuffers(sensor0ColorBufferData, sensor1ColorBufferData, numVertexBufferElems);

	/* Vertex buffers */

	GLuint sensor0VertexBuffer;
	glGenBuffers(1, &sensor0VertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor0VertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor0VertexBufferData, GL_STATIC_DRAW);

	GLuint sensor1VertexBuffer;
	glGenBuffers(1, &sensor1VertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor1VertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor1VertexBufferData, GL_STATIC_DRAW);

	/* Color buffers */

	GLuint sensor0ColorBuffer;
	glGenBuffers(1, &sensor0ColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor0ColorBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor0ColorBufferData, GL_STATIC_DRAW);

	GLuint sensor1ColorBuffer;
	glGenBuffers(1, &sensor1ColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor1ColorBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor1ColorBufferData, GL_STATIC_DRAW);

	do{
		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Use our shader
		glUseProgram(programID);

		// Compute the MVP matrix from keyboard and mouse input
		computeMatricesFromInputs();
		glm::mat4 ProjectionMatrix = getProjectionMatrix();
		glm::mat4 ViewMatrix = getViewMatrix();
		glm::mat4 ModelMatrix = glm::mat4(1.0);
		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

		// Enabled vertex attributes
		glEnableVertexAttribArray(vertexPosition_modelspaceID);
		glEnableVertexAttribArray(colorIntensityID);

		glBindBuffer(GL_ARRAY_BUFFER, sensor0VertexBuffer);
		glVertexAttribPointer(
			vertexPosition_modelspaceID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		glBindBuffer(GL_ARRAY_BUFFER, sensor0ColorBuffer);
		glVertexAttribPointer(
			colorIntensityID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the gesture for sensor 0
		glDrawArrays(GL_LINE_STRIP, 0, movementPairs.size()+1); // Initial position + movement pairs read from the file

		glBindBuffer(GL_ARRAY_BUFFER, sensor1VertexBuffer);
		glVertexAttribPointer(
			vertexPosition_modelspaceID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		glBindBuffer(GL_ARRAY_BUFFER, sensor1ColorBuffer);
		glVertexAttribPointer(
			colorIntensityID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the gesture for sensor 1
		glDrawArrays(GL_LINE_STRIP, 0, movementPairs.size()+1); // Initial position + movement pairs read from the file

		glDisableVertexAttribArray(vertexPosition_modelspaceID);

		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();

	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
		   glfwWindowShouldClose(window) == 0 );

	// Clean up buffers and shader
	glDeleteBuffers(1, &sensor0VertexBuffer);
	glDeleteBuffers(1, &sensor1VertexBuffer);

	glDeleteBuffers(1, &sensor0ColorBuffer);
	glDeleteBuffers(1, &sensor1ColorBuffer);

	glDeleteProgram(programID);
	glDeleteTextures(1, &TextureID);

	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	return 0;
}

<commit_msg>Viewer: Allow gestures to be fed via command line arguments<commit_after>// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include <cstring>

#include "letter_coordinates.hpp"

using namespace std;

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <glfw3.h>
GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

#include <common/shader.hpp>
//#include <common/texture.hpp>
#include <common/controls.hpp>

/* Constants */
#define STD_RADIUS 0.1
#define NO_ERROR 0

/* Forward declarations */
GLfloat getXVector (const double aPhi, const double aTheta);
GLfloat getYVector (const double aPhi, const double aTheta);
GLfloat getZVector (const double aTheta);

/* Obtained from http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html */
void Tokenize(const string& str,
				vector<string>& tokens,
				const string& delimiters)
{
	// Skip delimiters at beginning.
	string::size_type lastPos = str.find_first_not_of(delimiters, 0);
	// Find first "non-delimiter".
	string::size_type pos     = str.find_first_of(delimiters, lastPos);

	while (string::npos != pos || string::npos != lastPos)
	{
		// Found a token, add it to the vector.
		tokens.push_back(str.substr(lastPos, pos - lastPos));
		// Skip delimiters.  Note the "not_of"
		lastPos = str.find_first_not_of(delimiters, pos);
		// Find next "non-delimiter"
		pos = str.find_first_of(delimiters, lastPos);
	}
}

/*
 * Standard convention is:
 * x = r * sin THETA * cos PHI
 * y = r * sin THETA * sin PHI
 * z = r * cos THETA
 *
 * Here we set r = 0.1 and swap axes for OpenGL such that:
 * Std ---> OpenGL
 *  x  --->   z
 *  y  --->   x
 *  z  --->   y
 */

void getVectors(GLfloat &aDeltaX, GLfloat &aDeltaY, GLfloat &aDeltaZ, const double aPhi, const double aTheta)
{
	aDeltaX = getYVector(aPhi, aTheta);
	aDeltaY = getZVector(aTheta);
	aDeltaZ = getXVector(aPhi, aTheta);
}

GLfloat getXVector (const double aPhi, const double aTheta)
{
	return STD_RADIUS * sin(aTheta) * cos(aPhi);
}

GLfloat getYVector (const double aPhi, const double aTheta)
{
	return STD_RADIUS * sin(aTheta) * sin(aPhi);
}

GLfloat getZVector (const double aTheta)
{
	return STD_RADIUS * cos(aTheta);
}

void populateSensorVertexBuffers(int aSensorIndex, const vector<string>& aMovementsPairs, GLfloat* aSensorVertexBufferData) {
	//printf("sizeof(aSensorVertexBufferData): %li\n", sizeof(aSensorVertexBufferData));
	//printf("numVertexBufferElems: %li\n", numVertexBufferElems);
	GLfloat tempCoordinates[3] = { 0.0f, 0.0f, 0.0f };
	aSensorVertexBufferData[0] = 0.0f;
	aSensorVertexBufferData[1] = 0.0f;
	aSensorVertexBufferData[2] = 0.0f;
	for (int i = 0; i < aMovementsPairs.size(); i++) {
		int j = i * 3;
		string currentMovementPair = aMovementsPairs[i];
		//cout << currentMovementPair << endl;
		char currentMovement = currentMovementPair.c_str()[aSensorIndex];
		//cout << currentMovement << endl;
		/*
		 * Spherical gesture coordinates in PHI, THETA format
		 */
		GLfloat deltaX, deltaY, deltaZ;
		if (currentMovement == '_') {
			deltaX = 0.0f;
			deltaY = 0.0f;
			deltaZ = 0.0f;
		} else {
			struct sphericalCoordinates currentCoordinates =
					letterCoordinates[currentMovement];
			getVectors(deltaX, deltaY, deltaZ,
					degreesToRadians(currentCoordinates.mPhi),
					degreesToRadians(currentCoordinates.mTheta));
		}
		//cout << "movement " << currentS1Movement << " dx: " << deltaX << " dy: " << deltaY << " dz: " << deltaZ << endl;
		tempCoordinates[0] += deltaX;
		tempCoordinates[1] += deltaY;
		tempCoordinates[2] += deltaZ;
		aSensorVertexBufferData[j + 3] = tempCoordinates[0];
		aSensorVertexBufferData[j + 4] = tempCoordinates[1];
		aSensorVertexBufferData[j + 5] = tempCoordinates[2];
		//printf("vertex[%i, %i, %i] = {%f, %f, %f}\n", j+3, j+4, j+5, tempCoordinates[0], tempCoordinates[1], tempCoordinates[2]);
	}
}

void populateSensorColorBuffers(GLfloat* aSensor0ColorBufferData, GLfloat* aSensor1ColorBufferData, int aNumVertexBufferElems)
{
	int numMovements = aNumVertexBufferElems / 3;
	int numColorIntensityJumps = numMovements - 1;
	float colorIntensityInterval = 1.0f / numColorIntensityJumps;

	GLfloat sensor0TempIntensities[3] = { 0.0f, 0.0f, 0.0f }; // R,G,B
	GLfloat sensor1TempIntensities[3] = { 0.0f, 0.0f, 0.0f }; // R,G,B

	/* Origin is colored with intensity 0.0f */
	for (int i = 0; i < 3; i++) {
		aSensor0ColorBufferData[i] = 0.0f;
		aSensor1ColorBufferData[i] = 0.0f;
	}

	for (int i = 3; i < (aNumVertexBufferElems-2); i+=3) {
		cout << "i: " << i << endl;
		sensor0TempIntensities[0] += colorIntensityInterval; // Intensify red for sensor 0
		sensor1TempIntensities[2] += colorIntensityInterval; // Intensify blue for sensor 1

		aSensor0ColorBufferData[i] = sensor0TempIntensities[0];
		aSensor0ColorBufferData[i+1] = sensor0TempIntensities[1];
		aSensor0ColorBufferData[i+2] = sensor0TempIntensities[2];

		aSensor1ColorBufferData[i] = sensor1TempIntensities[0];
		aSensor1ColorBufferData[i+1] = sensor1TempIntensities[1];
		aSensor1ColorBufferData[i+2] = sensor1TempIntensities[2];
	}
}

void readGestureFromArguments(char* argv[], vector<string>& movementPairs) {
	string gesture(argv[2]);

	Tokenize(gesture, movementPairs, ".");
	cout << "Gesture: " << gesture << endl;
}

int readGestureFromFile(vector<string>& movementPairs) {
	ifstream gestureFile;
	gestureFile.open("gesture.dat");
	if (!gestureFile.is_open()) {
		return EXIT_FAILURE;
	}
	string line;
	if (!getline(gestureFile, line)) {
		return EXIT_FAILURE;
	}

	Tokenize(line, movementPairs, ".");
	cout << "Gesture: " << line << endl;

	return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		return -1;
	}

	glfwWindowHint(GLFW_SAMPLES, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

	// Open a window and create its OpenGL context
	window = glfwCreateWindow( 1280, 1024, "Gesture visualizer", NULL, NULL);
	if( window == NULL ){
		fprintf( stderr, "Failed to open GLFW window.\n" );
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	if (glewInit() != GLEW_OK) {
		fprintf(stderr, "Failed to initialize GLEW\n");
		return -1;
	}

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetCursorPos(window, 1280/2, 1024/2);

	// White background
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

	// Thick lines
	glLineWidth(3.0f);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);

	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LESS);

	// Cull triangles which normal is not towards the camera
	glEnable(GL_CULL_FACE);

	// Create and compile our GLSL program from the shaders
	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader" );

	// Get a handle for our "MVP" uniform
	GLuint MatrixID = glGetUniformLocation(programID, "MVP");

	// Get a handle for our buffers
	GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
	GLuint colorIntensityID = glGetAttribLocation(programID, "colorIntensity");
	//GLuint vertexUVID = glGetAttribLocation(programID, "vertexUV");

	// Get a handle for our "myTextureSampler" uniform
	GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");

	vector<string> movementPairs;

	if ((argc > 2) && (strncmp(argv[1], "--gesture", strlen("--gesture")) == 0)) {
		readGestureFromArguments(argv, movementPairs);
	} else {
		if (readGestureFromFile(movementPairs) != NO_ERROR) {
			cout << "Error reading gesture from file, exiting." << endl;
			return -1;
		}
	}

	long int numVertexBufferElems = (movementPairs.size()+1) * 3; // One extra entry at the beginning for coordinate {0.0f, 0.0f, 0.0f}

	GLfloat* sensor0VertexBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor0ColorBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor1VertexBufferData = new GLfloat[numVertexBufferElems];
	GLfloat* sensor1ColorBufferData = new GLfloat[numVertexBufferElems];

	populateSensorVertexBuffers(0, movementPairs, sensor0VertexBufferData);
	populateSensorVertexBuffers(1, movementPairs, sensor1VertexBufferData);
	populateSensorColorBuffers(sensor0ColorBufferData, sensor1ColorBufferData, numVertexBufferElems);

	/* Vertex buffers */

	GLuint sensor0VertexBuffer;
	glGenBuffers(1, &sensor0VertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor0VertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor0VertexBufferData, GL_STATIC_DRAW);

	GLuint sensor1VertexBuffer;
	glGenBuffers(1, &sensor1VertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor1VertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor1VertexBufferData, GL_STATIC_DRAW);

	/* Color buffers */

	GLuint sensor0ColorBuffer;
	glGenBuffers(1, &sensor0ColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor0ColorBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor0ColorBufferData, GL_STATIC_DRAW);

	GLuint sensor1ColorBuffer;
	glGenBuffers(1, &sensor1ColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, sensor1ColorBuffer);
	glBufferData(GL_ARRAY_BUFFER, numVertexBufferElems * sizeof(GLfloat), sensor1ColorBufferData, GL_STATIC_DRAW);

	do{
		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Use our shader
		glUseProgram(programID);

		// Compute the MVP matrix from keyboard and mouse input
		computeMatricesFromInputs();
		glm::mat4 ProjectionMatrix = getProjectionMatrix();
		glm::mat4 ViewMatrix = getViewMatrix();
		glm::mat4 ModelMatrix = glm::mat4(1.0);
		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

		// Enabled vertex attributes
		glEnableVertexAttribArray(vertexPosition_modelspaceID);
		glEnableVertexAttribArray(colorIntensityID);

		glBindBuffer(GL_ARRAY_BUFFER, sensor0VertexBuffer);
		glVertexAttribPointer(
			vertexPosition_modelspaceID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		glBindBuffer(GL_ARRAY_BUFFER, sensor0ColorBuffer);
		glVertexAttribPointer(
			colorIntensityID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the gesture for sensor 0
		glDrawArrays(GL_LINE_STRIP, 0, movementPairs.size()+1); // Initial position + movement pairs read from the file

		glBindBuffer(GL_ARRAY_BUFFER, sensor1VertexBuffer);
		glVertexAttribPointer(
			vertexPosition_modelspaceID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		glBindBuffer(GL_ARRAY_BUFFER, sensor1ColorBuffer);
		glVertexAttribPointer(
			colorIntensityID, // The attribute we want to configure
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the gesture for sensor 1
		glDrawArrays(GL_LINE_STRIP, 0, movementPairs.size()+1); // Initial position + movement pairs read from the file

		glDisableVertexAttribArray(vertexPosition_modelspaceID);

		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();

	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
		   glfwWindowShouldClose(window) == 0 );

	// Clean up buffers and shader
	glDeleteBuffers(1, &sensor0VertexBuffer);
	glDeleteBuffers(1, &sensor1VertexBuffer);

	glDeleteBuffers(1, &sensor0ColorBuffer);
	glDeleteBuffers(1, &sensor1ColorBuffer);

	glDeleteProgram(programID);
	glDeleteTextures(1, &TextureID);

	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	return 0;
}

<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_LAYERS_HH
#define DUNE_STUFF_GRID_LAYERS_HH

#include <memory>

#if HAVE_DUNE_FEM
# include <dune/stuff/common/disable_warnings.hh>
#   include <dune/fem/gridpart/leafgridpart.hh>
#   include <dune/fem/gridpart/levelgridpart.hh>
# include <dune/stuff/common/reenable_warnings.hh>
#endif // HAVE_DUNE_FEM

#if HAVE_DUNE_GRID_MULTISCALE
# include <dune/grid/multiscale/default.hh>
#endif

namespace Dune {
namespace Stuff {
namespace Grid {

enum class ChoosePartView
{
    view
  , part
}; // enum class ChoosePartView

enum class ChooseLayer
{
    level
  , leaf
#if HAVE_DUNE_GRID_MULTISCALE
  , local
  , local_oversampled
#endif
}; // enum class ChooseLayer

#if HAVE_DUNE_GRID

// forwards
template< class GridType, ChooseLayer layer, ChoosePartView part_view >
struct Layer;

template< class GridType, ChoosePartView type >
struct LevelPartView;

template< class GridType, ChoosePartView type >
struct LeafPartView;

template< class GridType, ChooseLayer type >
struct LayerView;

template< class GridType, ChooseLayer type >
struct LayerPart;

template< class GridType >
struct Layer< GridType, ChooseLayer::level, ChoosePartView::view >
{
  typedef typename GridType::LevelGridView Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    assert(level >= 0);
    assert(level <= grid.maxLevel());
    return std::make_shared< Type >(grid.levelGridView(level));
  } // ... create(...)
}; // struct Layer< ..., level, view >

template< class GridType >
struct Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >
{
  typedef typename GridType::LeafGridView Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return std::make_shared< Type >(grid.leafGridView());
  }
}; // struct Layer< ..., leaf, view >

# if HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct Layer< GridType, ChooseLayer::local, ChoosePartView::view >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridViewType Type;
};

template< class GridType >
struct Layer< GridType, ChooseLayer::local_oversampled, ChoosePartView::view >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridViewType Type;
};

# endif // HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct LevelPartView< GridType, ChoosePartView::view >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid, level);
  }
}; // struct LevelPartView< ..., view >

template< class GridType >
struct LeafPartView< GridType, ChoosePartView::view >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::create(grid);
  }
}; // struct LeafPartView< ..., view >

template< class GridType >
struct LayerView< GridType, ChooseLayer::level >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid, level);
  }
}; // struct LayerView< ..., level >

template< class GridType >
struct LayerView< GridType, ChooseLayer::leaf >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid);
  }
}; // struct LayerView< ..., leaf >

# if HAVE_DUNE_FEM

/** dune-fem Leaf/LevelGridParts are a little funky in that their
 * GridViewType is entirely incompatible with the "real"
 * leaf/level gridview. To fix this we're injecting our own tiny
 * GridParts instead
 **/

template< class GridType >
struct Layer< GridType, ChooseLayer::level, ChoosePartView::part >
{
  typedef Dune::Fem::LevelGridPart< GridType > RealType;
  struct Type : public RealType {
    typedef typename RealType::LevelGridView GridViewType;
    explicit Type(GridType& g) : RealType(g) {}
    Type(GridType& g, const int l) : RealType(g, l) {}
    GridViewType gridView () const { return GridViewType(RealType::grid(), RealType::level()); }
  };

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    assert(level >= 0);
    assert(level <= grid.maxLevel());
    return std::make_shared< Type >(grid, level);
  } // ... create(...)
}; // struct Layer< ..., level, part >

template< class GridType >
struct Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >
{
  typedef Dune::Fem::LeafGridPart< GridType > RealType;
  struct Type : public RealType {
    typedef typename RealType::LeafGridView GridViewType;
    explicit Type(GridType& g) : RealType(g) {}
    GridViewType gridView () const { return RealType::grid().leafGridView(); }
  };

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return std::make_shared< Type >(grid);
  }
}; // struct Layer< ..., leaf, part >

#   if HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct Layer< GridType, ChooseLayer::local, ChoosePartView::part >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridPartType Type;
};

template< class GridType >
struct Layer< GridType, ChooseLayer::local_oversampled, ChoosePartView::part >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridPartType Type;
};

#   endif // HAVE_DUNE_GRID_MULTISCALE

template< class GridType>
struct LevelPartView< GridType, ChoosePartView::part >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::part >::create(grid, level);
  }
}; // struct LevelPartView< ..., part >

template< class GridType >
struct LeafPartView< GridType, ChoosePartView::part >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::create(grid);
  }
}; // struct LeafPartView< ..., part >

template< class GridType>
struct LayerPart< GridType, ChooseLayer::level >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::part >::create(grid, level);
  }
}; // struct LayerPart< ..., level >

template< class GridType>
struct LayerPart< GridType, ChooseLayer::leaf >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::create(grid);
  }
}; // struct LayerPart< ..., leaf >

# endif // HAVE_DUNE_FEM
#else // HAVE_DUNE_GRID

template< class GridType, ChooseLayer layer, ChoosePartView type >
struct Layer
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

template< class GridType, ChoosePartView type >
struct LevelPartView
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

template< class GridType, ChoosePartView type >
struct LeafPartView
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_LAYERS_HH
<commit_msg>Revert "[grid] Layer templates now carry own GridPartTypes"<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_LAYERS_HH
#define DUNE_STUFF_GRID_LAYERS_HH

#include <memory>

#if HAVE_DUNE_FEM
# include <dune/stuff/common/disable_warnings.hh>
#   include <dune/fem/gridpart/leafgridpart.hh>
#   include <dune/fem/gridpart/levelgridpart.hh>
# include <dune/stuff/common/reenable_warnings.hh>
#endif // HAVE_DUNE_FEM

#if HAVE_DUNE_GRID_MULTISCALE
# include <dune/grid/multiscale/default.hh>
#endif

namespace Dune {
namespace Stuff {
namespace Grid {

enum class ChoosePartView
{
    view
  , part
}; // enum class ChoosePartView

enum class ChooseLayer
{
    level
  , leaf
#if HAVE_DUNE_GRID_MULTISCALE
  , local
  , local_oversampled
#endif
}; // enum class ChooseLayer

#if HAVE_DUNE_GRID

// forwards
template< class GridType, ChooseLayer layer, ChoosePartView part_view >
struct Layer;

template< class GridType, ChoosePartView type >
struct LevelPartView;

template< class GridType, ChoosePartView type >
struct LeafPartView;

template< class GridType, ChooseLayer type >
struct LayerView;

template< class GridType, ChooseLayer type >
struct LayerPart;

template< class GridType >
struct Layer< GridType, ChooseLayer::level, ChoosePartView::view >
{
  typedef typename GridType::LevelGridView Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    assert(level >= 0);
    assert(level <= grid.maxLevel());
    return std::make_shared< Type >(grid.levelGridView(level));
  } // ... create(...)
}; // struct Layer< ..., level, view >

template< class GridType >
struct Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >
{
  typedef typename GridType::LeafGridView Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return std::make_shared< Type >(grid.leafGridView());
  }
}; // struct Layer< ..., leaf, view >

# if HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct Layer< GridType, ChooseLayer::local, ChoosePartView::view >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridViewType Type;
};

template< class GridType >
struct Layer< GridType, ChooseLayer::local_oversampled, ChoosePartView::view >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridViewType Type;
};

# endif // HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct LevelPartView< GridType, ChoosePartView::view >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid, level);
  }
}; // struct LevelPartView< ..., view >

template< class GridType >
struct LeafPartView< GridType, ChoosePartView::view >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::create(grid);
  }
}; // struct LeafPartView< ..., view >

template< class GridType >
struct LayerView< GridType, ChooseLayer::level >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid, level);
  }
}; // struct LayerView< ..., level >

template< class GridType >
struct LayerView< GridType, ChooseLayer::leaf >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::view >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::view >::create(grid);
  }
}; // struct LayerView< ..., leaf >

# if HAVE_DUNE_FEM

template< class GridType >
struct Layer< GridType, ChooseLayer::level, ChoosePartView::part >
{
  typedef Dune::Fem::LevelGridPart< GridType > Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    assert(level >= 0);
    assert(level <= grid.maxLevel());
    return std::make_shared< Type >(grid, level);
  } // ... create(...)
}; // struct Layer< ..., level, part >

template< class GridType >
struct Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >
{
  typedef Dune::Fem::LeafGridPart< GridType > Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return std::make_shared< Type >(grid);
  }
}; // struct Layer< ..., leaf, part >

#   if HAVE_DUNE_GRID_MULTISCALE

template< class GridType >
struct Layer< GridType, ChooseLayer::local, ChoosePartView::part >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridPartType Type;
};

template< class GridType >
struct Layer< GridType, ChooseLayer::local_oversampled, ChoosePartView::part >
{
  typedef typename grid::Multiscale::Default< GridType >::LocalGridPartType Type;
};

#   endif // HAVE_DUNE_GRID_MULTISCALE

template< class GridType>
struct LevelPartView< GridType, ChoosePartView::part >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::part >::create(grid, level);
  }
}; // struct LevelPartView< ..., part >

template< class GridType >
struct LeafPartView< GridType, ChoosePartView::part >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::create(grid);
  }
}; // struct LeafPartView< ..., part >

template< class GridType>
struct LayerPart< GridType, ChooseLayer::level >
{
  typedef typename Layer< GridType, ChooseLayer::level, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int level)
  {
    return Layer< GridType, ChooseLayer::level, ChoosePartView::part >::create(grid, level);
  }
}; // struct LayerPart< ..., level >

template< class GridType>
struct LayerPart< GridType, ChooseLayer::leaf >
{
  typedef typename Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::Type Type;

  static std::shared_ptr< Type > create(GridType& grid, const int /*level*/ = 0)
  {
    return Layer< GridType, ChooseLayer::leaf, ChoosePartView::part >::create(grid);
  }
}; // struct LayerPart< ..., leaf >

# endif // HAVE_DUNE_FEM
#else // HAVE_DUNE_GRID

template< class GridType, ChooseLayer layer, ChoosePartView type >
struct Layer
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

template< class GridType, ChoosePartView type >
struct LevelPartView
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

template< class GridType, ChoosePartView type >
struct LeafPartView
{
  static_assert(AlwaysFalse< GridType >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_LAYERS_HH
<|endoftext|>


<commit_before>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/compiler/tf2xla/lib/batch_dot.h"

#include <memory>
#include <vector>

#include "tensorflow/compiler/xla/client/xla_builder.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/status_macros.h"
#include "tensorflow/compiler/xla/statusor.h"
#include "tensorflow/core/lib/core/errors.h"

namespace tensorflow {

xla::XlaOp BatchDot(xla::XlaOp x, xla::XlaOp y, bool transpose_x,
                    bool transpose_y, bool conjugate_x, bool conjugate_y,
                    xla::PrecisionConfig::Precision precision) {
  xla::XlaBuilder* builder = x.builder();
  return builder->ReportErrorOrReturn([&]() -> xla::StatusOr<xla::XlaOp> {
    TF_ASSIGN_OR_RETURN(xla::Shape x_shape, builder->GetShape(x));
    TF_ASSIGN_OR_RETURN(xla::Shape y_shape, builder->GetShape(y));

    // Check that both tensors have the same number of dimensions. There must be
    // at least two (the batch dimensions can be empty).
    if (xla::ShapeUtil::Rank(x_shape) != xla::ShapeUtil::Rank(y_shape)) {
      return errors::InvalidArgument(
          "Arguments to BatchedDot have different ranks: ",
          xla::ShapeUtil::HumanString(x_shape), " vs. ",
          xla::ShapeUtil::HumanString(y_shape));
    }
    const int ndims = xla::ShapeUtil::Rank(x_shape);
    if (ndims < 2) {
      return errors::InvalidArgument(
          "Arguments to BatchedDot must have rank >= 2: ", ndims);
    }

    // The batch dimensions must be equal and the matrix dimensions must be
    // valid.
    std::vector<int64> batch_dimension_numbers;
    for (int i = 0; i < ndims - 2; ++i) {
      if (x_shape.dimensions(i) != y_shape.dimensions(i)) {
        return errors::InvalidArgument(
            "Dimension ", i, " of inputs to BatchedDot must be equal: ",
            xla::ShapeUtil::HumanString(x_shape), " vs ",
            xla::ShapeUtil::HumanString(y_shape));
      }
      batch_dimension_numbers.push_back(i);
    }

    int x_inner_dim = transpose_x ? (ndims - 2) : (ndims - 1);
    int y_inner_dim = transpose_y ? (ndims - 1) : (ndims - 2);
    if (x_shape.dimensions(x_inner_dim) != y_shape.dimensions(y_inner_dim)) {
      return errors::InvalidArgument(
          "Dimensions ", x_inner_dim, " and ", y_inner_dim,
          " of arguments to BatchedDot must be equal: ",
          xla::ShapeUtil::HumanString(x_shape), " transpose: ", transpose_x,
          " vs. ", xla::ShapeUtil::HumanString(y_shape),
          " transpose: ", transpose_y);
    }

    // Check for zero lhs/rhs dim size.
    if (xla::ShapeUtil::IsZeroElementArray(x_shape) ||
        xla::ShapeUtil::IsZeroElementArray(y_shape)) {
      std::vector<int64> dimensions(batch_dimension_numbers.size());
      for (int i = 0; i < batch_dimension_numbers.size(); ++i) {
        dimensions[i] = x_shape.dimensions(batch_dimension_numbers[i]);
      }
      int x_outer_dim = transpose_x ? (ndims - 1) : (ndims - 2);
      int y_outer_dim = transpose_y ? (ndims - 2) : (ndims - 1);
      dimensions.push_back(x_shape.dimensions(x_outer_dim));
      dimensions.push_back(y_shape.dimensions(y_outer_dim));
      return xla::Broadcast(
          xla::ConstantLiteral(builder,
                               xla::LiteralUtil::Zero(x_shape.element_type())),
          dimensions);
    }

    if (x_shape.element_type() == xla::C64 && conjugate_x) {
      x = xla::Conj(x);
    }
    if (y_shape.element_type() == xla::C64 && conjugate_y) {
      y = xla::Conj(y);
    }

    xla::PrecisionConfig precision_proto;
    precision_proto.add_operand_precision(precision);
    precision_proto.add_operand_precision(precision);

    // If there are no batch dimensions, use a regular Dot.
    // TODO(b/69062148) Remove this code when Dot emitters can be passed
    // dimensions to transpose directly (i.e. without requiring a Transpose
    // HLO).
    if (batch_dimension_numbers.empty()) {
      auto lhs = transpose_x ? xla::Transpose(x, {1, 0}) : x;
      auto rhs = transpose_y ? xla::Transpose(y, {1, 0}) : y;
      return xla::Dot(lhs, rhs, &precision_proto);
    }

    xla::DotDimensionNumbers dot_dnums;
    dot_dnums.add_lhs_contracting_dimensions(x_inner_dim);
    dot_dnums.add_rhs_contracting_dimensions(y_inner_dim);
    for (auto batch_dimension_number : batch_dimension_numbers) {
      dot_dnums.add_lhs_batch_dimensions(batch_dimension_number);
      dot_dnums.add_rhs_batch_dimensions(batch_dimension_number);
    }

    return xla::DotGeneral(x, y, dot_dnums, &precision_proto);
  });
}

}  // namespace tensorflow
<commit_msg>[TF:XLA] Remove special base case from BatchDot that has been redundant ever since xla::DotGeneral was added.<commit_after>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/compiler/tf2xla/lib/batch_dot.h"

#include <memory>
#include <vector>

#include "tensorflow/compiler/xla/client/xla_builder.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/status_macros.h"
#include "tensorflow/compiler/xla/statusor.h"
#include "tensorflow/core/lib/core/errors.h"

namespace tensorflow {

xla::XlaOp BatchDot(xla::XlaOp x, xla::XlaOp y, bool transpose_x,
                    bool transpose_y, bool conjugate_x, bool conjugate_y,
                    xla::PrecisionConfig::Precision precision) {
  xla::XlaBuilder* builder = x.builder();
  return builder->ReportErrorOrReturn([&]() -> xla::StatusOr<xla::XlaOp> {
    TF_ASSIGN_OR_RETURN(xla::Shape x_shape, builder->GetShape(x));
    TF_ASSIGN_OR_RETURN(xla::Shape y_shape, builder->GetShape(y));

    // Check that both tensors have the same number of dimensions. There must be
    // at least two (the batch dimensions can be empty).
    if (xla::ShapeUtil::Rank(x_shape) != xla::ShapeUtil::Rank(y_shape)) {
      return errors::InvalidArgument(
          "Arguments to BatchedDot have different ranks: ",
          xla::ShapeUtil::HumanString(x_shape), " vs. ",
          xla::ShapeUtil::HumanString(y_shape));
    }
    const int ndims = xla::ShapeUtil::Rank(x_shape);
    if (ndims < 2) {
      return errors::InvalidArgument(
          "Arguments to BatchedDot must have rank >= 2: ", ndims);
    }

    // The batch dimensions must be equal and the matrix dimensions must be
    // valid.
    std::vector<int64> batch_dimension_numbers;
    for (int i = 0; i < ndims - 2; ++i) {
      if (x_shape.dimensions(i) != y_shape.dimensions(i)) {
        return errors::InvalidArgument(
            "Dimension ", i, " of inputs to BatchedDot must be equal: ",
            xla::ShapeUtil::HumanString(x_shape), " vs ",
            xla::ShapeUtil::HumanString(y_shape));
      }
      batch_dimension_numbers.push_back(i);
    }

    int x_inner_dim = transpose_x ? (ndims - 2) : (ndims - 1);
    int y_inner_dim = transpose_y ? (ndims - 1) : (ndims - 2);
    if (x_shape.dimensions(x_inner_dim) != y_shape.dimensions(y_inner_dim)) {
      return errors::InvalidArgument(
          "Dimensions ", x_inner_dim, " and ", y_inner_dim,
          " of arguments to BatchedDot must be equal: ",
          xla::ShapeUtil::HumanString(x_shape), " transpose: ", transpose_x,
          " vs. ", xla::ShapeUtil::HumanString(y_shape),
          " transpose: ", transpose_y);
    }

    // Check for zero lhs/rhs dim size.
    if (xla::ShapeUtil::IsZeroElementArray(x_shape) ||
        xla::ShapeUtil::IsZeroElementArray(y_shape)) {
      std::vector<int64> dimensions(batch_dimension_numbers.size());
      for (int i = 0; i < batch_dimension_numbers.size(); ++i) {
        dimensions[i] = x_shape.dimensions(batch_dimension_numbers[i]);
      }
      int x_outer_dim = transpose_x ? (ndims - 1) : (ndims - 2);
      int y_outer_dim = transpose_y ? (ndims - 2) : (ndims - 1);
      dimensions.push_back(x_shape.dimensions(x_outer_dim));
      dimensions.push_back(y_shape.dimensions(y_outer_dim));
      return xla::Broadcast(
          xla::ConstantLiteral(builder,
                               xla::LiteralUtil::Zero(x_shape.element_type())),
          dimensions);
    }

    if (x_shape.element_type() == xla::C64 && conjugate_x) {
      x = xla::Conj(x);
    }
    if (y_shape.element_type() == xla::C64 && conjugate_y) {
      y = xla::Conj(y);
    }

    xla::PrecisionConfig precision_proto;
    precision_proto.add_operand_precision(precision);
    precision_proto.add_operand_precision(precision);

    xla::DotDimensionNumbers dot_dnums;
    dot_dnums.add_lhs_contracting_dimensions(x_inner_dim);
    dot_dnums.add_rhs_contracting_dimensions(y_inner_dim);
    for (auto batch_dimension_number : batch_dimension_numbers) {
      dot_dnums.add_lhs_batch_dimensions(batch_dimension_number);
      dot_dnums.add_rhs_batch_dimensions(batch_dimension_number);
    }

    return xla::DotGeneral(x, y, dot_dnums, &precision_proto);
  });
}

}  // namespace tensorflow
<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <tuple>
#include <regex>
#include <array>
#include <valarray>
#define all(v)begin(v),end(v)
#define dump(v)copy(all(v),ostream_iterator<decltype(*v.begin())>(cout,"\n"))
#define rg(i,a,b)for(int i=a,i##e=b;i<i##e;++i)
#define fr(i,n)for(int i=0,i##e=n;i<i##e;++i)
#define rf(i,n)for(int i=n-1;i>=0;--i)
#define ei(a,m)for(auto&a:m)if(int a##i=&a-&*begin(m)+1)if(--a##i,1)
#define sz(v)int(v.size())
#define sr(v)sort(all(v))
#define rs(v)sort(all(v),greater<int>())
#define rev(v)reverse(all(v))
#define eb emplace_back
#define stst stringstream
#define big numeric_limits<int>::max()
#define g(t,i)get<i>(t)
#define cb(v,w)copy(all(v),back_inserter(w))
#define uni(v)sort(all(v));v.erase(unique(all(v)),end(v))
#define vt(...)vector<tuple<__VA_ARGS__>>
#define smx(a,b)a=max(a,b)
#define smn(a,b)a=min(a,b)
#define words(w,q)vector<string>w;[&w](string&&s){stringstream u(s);string r;while(u>>r)w.eb(r);}(q);
#define digits(d,n,s)vector<int>d;[&d](int m){while(m)d.eb(m%s),m/=s;}(n);
typedef long long ll;
using namespace std;

struct DeckRearranging {
	string rearrange(string deck, vector <int> above) {
		string r;
		ei(a, deck) {
			r = r.substr(0, sz(r) - above[ai]) + a + r.substr(sz(r) - above[ai]);
		}
		return r;
	}
};

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit-pf 2.3.0
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
bool KawigiEdit_RunTest(int testNum, string p0, vector <int> p1, bool hasAnswer, string p2) {
	cout << "Test " << testNum << ": [" << "\"" << p0 << "\"" << "," << "{";
	for (int i = 0; int(p1.size()) > i; ++i) {
		if (i > 0) {
			cout << ",";
		}
		cout << p1[i];
	}
	cout << "}";
	cout << "]" << endl;
	DeckRearranging *obj;
	string answer;
	obj = new DeckRearranging();
	clock_t startTime = clock();
	answer = obj->rearrange(p0, p1);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << "\"" << p2 << "\"" << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << "\"" << answer << "\"" << endl;
	if (hasAnswer) {
		res = answer == p2;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	bool disabled;
	bool tests_disabled;
	all_right = true;
	tests_disabled = false;

	string p0;
	vector <int> p1;
	string p2;

	// ----- test 0 -----
	disabled = false;
	p0 = "BRBRR";
	p1 = {0,0,1,0,3};
	p2 = "RRBRB";
	all_right = (disabled || KawigiEdit_RunTest(0, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 1 -----
	disabled = false;
	p0 = "RRRRRR";
	p1 = {0,1,2,0,1,3};
	p2 = "RRRRRR";
	all_right = (disabled || KawigiEdit_RunTest(1, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 2 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,1,2,3,4,5,6,7};
	p2 = "RBRRBRBB";
	all_right = (disabled || KawigiEdit_RunTest(2, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 3 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,0,0,0,0,0,0,0};
	p2 = "BBRBRRBR";
	all_right = (disabled || KawigiEdit_RunTest(3, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 4 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,1,0,0,4,0,6,7};
	p2 = "RRRRBBBB";
	all_right = (disabled || KawigiEdit_RunTest(4, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	if (all_right) {
		if (tests_disabled) {
			cout << "You're a stud (but some test cases were disabled)!" << endl;
		} else {
			cout << "You're a stud (at least on given cases)!" << endl;
		}
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
<commit_msg>DeckRearranging<commit_after>#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <tuple>
#include <regex>
#include <array>
#include <valarray>
#define all(v)begin(v),end(v)
#define dump(v)copy(all(v),ostream_iterator<decltype(*v.begin())>(cout,"\n"))
#define rg(i,a,b)for(int i=a,i##e=b;i<i##e;++i)
#define fr(i,n)for(int i=0,i##e=n;i<i##e;++i)
#define rf(i,n)for(int i=n-1;i>=0;--i)
#define ei(a,m)for(auto&a:m)if(int a##i=&a-&*begin(m)+1)if(--a##i,1)
#define sz(v)int(v.size())
#define sr(v)sort(all(v))
#define rs(v)sort(all(v),greater<int>())
#define rev(v)reverse(all(v))
#define eb emplace_back
#define stst stringstream
#define big numeric_limits<int>::max()
#define g(t,i)get<i>(t)
#define cb(v,w)copy(all(v),back_inserter(w))
#define uni(v)sort(all(v));v.erase(unique(all(v)),end(v))
#define vt(...)vector<tuple<__VA_ARGS__>>
#define smx(a,b)a=max(a,b)
#define smn(a,b)a=min(a,b)
#define words(w,q)vector<string>w;[&w](string&&s){stringstream u(s);string r;while(u>>r)w.eb(r);}(q);
#define digits(d,n,s)vector<int>d;[&d](int m){while(m)d.eb(m%s),m/=s;}(n);
typedef long long ll;
using namespace std;

struct DeckRearranging {
	string rearrange(string deck, vector <int> above) {
		string r;
		ei(a, deck) {
			r = r.substr(0, above[ai]) + a + r.substr(above[ai]);
		}
		return r;
	}
};

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit-pf 2.3.0
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
bool KawigiEdit_RunTest(int testNum, string p0, vector <int> p1, bool hasAnswer, string p2) {
	cout << "Test " << testNum << ": [" << "\"" << p0 << "\"" << "," << "{";
	for (int i = 0; int(p1.size()) > i; ++i) {
		if (i > 0) {
			cout << ",";
		}
		cout << p1[i];
	}
	cout << "}";
	cout << "]" << endl;
	DeckRearranging *obj;
	string answer;
	obj = new DeckRearranging();
	clock_t startTime = clock();
	answer = obj->rearrange(p0, p1);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << "\"" << p2 << "\"" << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << "\"" << answer << "\"" << endl;
	if (hasAnswer) {
		res = answer == p2;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	bool disabled;
	bool tests_disabled;
	all_right = true;
	tests_disabled = false;

	string p0;
	vector <int> p1;
	string p2;

	// ----- test 0 -----
	disabled = false;
	p0 = "BRBRR";
	p1 = {0,0,1,0,3};
	p2 = "RRBRB";
	all_right = (disabled || KawigiEdit_RunTest(0, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 1 -----
	disabled = false;
	p0 = "RRRRRR";
	p1 = {0,1,2,0,1,3};
	p2 = "RRRRRR";
	all_right = (disabled || KawigiEdit_RunTest(1, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 2 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,1,2,3,4,5,6,7};
	p2 = "RBRRBRBB";
	all_right = (disabled || KawigiEdit_RunTest(2, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 3 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,0,0,0,0,0,0,0};
	p2 = "BBRBRRBR";
	all_right = (disabled || KawigiEdit_RunTest(3, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 4 -----
	disabled = false;
	p0 = "RBRRBRBB";
	p1 = {0,1,0,0,4,0,6,7};
	p2 = "RRRRBBBB";
	all_right = (disabled || KawigiEdit_RunTest(4, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	if (all_right) {
		if (tests_disabled) {
			cout << "You're a stud (but some test cases were disabled)!" << endl;
		} else {
			cout << "You're a stud (at least on given cases)!" << endl;
		}
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
<|endoftext|>


<commit_before>#include "mintingtablemodel.h"
#include "transactiontablemodel.h"
#include "guiutil.h"
#include "kernelrecord.h"
#include "guiconstants.h"
#include "transactiondesc.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "addresstablemodel.h"
#include "bitcoinunits.h"
#include "util.h"
#include "kernel.h"

#include "wallet.h"

#include <QLocale>
#include <QList>
#include <QColor>
#include <QTimer>
#include <QIcon>
#include <QDateTime>
#include <QtAlgorithms>

static int column_alignments[] = {
    Qt::AlignLeft|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter
};

struct TxLessThan
{
    bool operator()(const KernelRecord &a, const KernelRecord &b) const
    {
        return a.hash < b.hash;
    }
    bool operator()(const KernelRecord &a, const uint256 &b) const
    {
        return a.hash < b;
    }
    bool operator()(const uint256 &a, const KernelRecord &b) const
    {
        return a < b.hash;
    }
};

class MintingTablePriv
{
public:
    MintingTablePriv(CWallet *wallet, MintingTableModel *parent):
        wallet(wallet),
        parent(parent)
    {
    }
    CWallet *wallet;
    MintingTableModel *parent;

    QList<KernelRecord> cachedWallet;

    void refreshWallet()
    {
#ifdef WALLET_UPDATE_DEBUG
        qDebug() << "refreshWallet";
#endif
        cachedWallet.clear();
        {
            LOCK(wallet->cs_wallet);
            for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
            {
                QList<KernelRecord> txList = KernelRecord::decomposeOutput(wallet, it->second);
                for(QList<KernelRecord>::iterator i = txList.begin(); i != txList.end(); ++i) {
                    if(!(*i).spent) {
                        cachedWallet.append(*i);
                    }
                }

            }
        }
    }

    /* Update our model of the wallet incrementally, to synchronize our model of the wallet
       with that of the core.

       Call with list of hashes of transactions that were added, removed or changed.
     */
    void updateWallet(const QList<uint256> &updated)
    {
        // Walk through updated transactions, update model as needed.
#ifdef WALLET_UPDATE_DEBUG
        qDebug() << "updateWallet";
#endif
        // Sort update list, and iterate through it in reverse, so that model updates
        //  can be emitted from end to beginning (so that earlier updates will not influence
        // the indices of latter ones).
        QList<uint256> updated_sorted = updated;
        qSort(updated_sorted);

        {
            LOCK(wallet->cs_wallet);
            for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
            {
                const uint256 &hash = updated_sorted.at(update_idx);
                // Find transaction in wallet
                std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
                bool inWallet = mi != wallet->mapWallet.end();
                // Find bounds of this transaction in model
                QList<KernelRecord>::iterator lower = qLowerBound(
                    cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
                QList<KernelRecord>::iterator upper = qUpperBound(
                    cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
                int lowerIndex = (lower - cachedWallet.begin());
                int upperIndex = (upper - cachedWallet.begin());

                // Determine if transaction is in model already
                bool inModel = false;
                if(lower != upper)
                {
                    inModel = true;
                }

#ifdef WALLET_UPDATE_DEBUG
                qDebug() << "  " << QString::fromStdString(hash.ToString()) << inWallet << " " << inModel
                        << lowerIndex << "-" << upperIndex;
#endif

                if(inWallet && !inModel)
                {
                    // Added -- insert at the right position
                    QList<KernelRecord> toInsert =
                            KernelRecord::decomposeOutput(wallet, mi->second);
                    if(!toInsert.isEmpty()) /* only if something to insert */
                    {
                        parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
                        int insert_idx = lowerIndex;
                        foreach(const KernelRecord &rec, toInsert)
                        {
                            if(!rec.spent) {
                                cachedWallet.insert(insert_idx, rec);
                                insert_idx += 1;
                            }
                        }
                        parent->endInsertRows();
                    }
                }
                else if(!inWallet && inModel)
                {
                    // Removed -- remove entire transaction from table
                    parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
                    cachedWallet.erase(lower, upper);
                    parent->endRemoveRows();
                }
                else if(inWallet && inModel)
                {
                    // Updated -- nothing to do, status update will take care of this
                }
            }
        }
    }

    int size()
    {
        return cachedWallet.size();
    }

    KernelRecord *index(int idx)
    {
        if(idx >= 0 && idx < cachedWallet.size())
        {
            KernelRecord *rec = &cachedWallet[idx];
            return rec;
        }
        else
        {
            return 0;
        }
    }

    QString describe(KernelRecord *rec)
    {
        {
            LOCK(wallet->cs_wallet);
            std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
            if(mi != wallet->mapWallet.end())
            {
                return TransactionDesc::toHTML(wallet, mi->second);
            }
        }
        return QString("");
    }

};

MintingTableModel::MintingTableModel(CWallet *wallet, WalletModel *parent):
        QAbstractTableModel(parent),
        wallet(wallet),
        walletModel(parent),
        mintingInterval(10),
        priv(new MintingTablePriv(wallet, this))
{
    columns << tr("Address") << tr("Age") << tr("Balance") << tr("CoinDay") << tr("MintProbability");
    priv->refreshWallet();

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(MODEL_UPDATE_DELAY);
}

MintingTableModel::~MintingTableModel()
{
    delete priv;
}

void MintingTableModel::update()
{
    QList<uint256> updated;

    {
        TRY_LOCK(wallet->cs_wallet, lockWallet);
        if (lockWallet && !wallet->vWalletUpdated.empty())
        {
            BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
            {
                updated.append(hash);
            }
            wallet->vWalletUpdated.clear();
        }
    }

    if(!updated.empty())
    {
        priv->updateWallet(updated);
    }
}

int MintingTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int MintingTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant MintingTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    KernelRecord *rec = static_cast<KernelRecord*>(index.internalPointer());
    switch(role)
    {
      case Qt::DisplayRole:
        switch(index.column())
        {
        case Address:
            return formatTxAddress(rec, false);
        case Age:
            return formatTxAge(rec);
        case Balance:
            return formatTxBalance(rec);
        case CoinDay:
            return formatTxCoinDay(rec);
        case MintProbability:
            return formatDayToMint(rec);
        }
        break;
      case Qt::TextAlignmentRole:
        return column_alignments[index.column()];
        break;

      case Qt::EditRole:
        switch(index.column())
        {
        case Address:
            return formatTxAddress(rec, false);
        case Age:
            return formatTxAge(rec);
        case CoinDay:
            return formatTxCoinDay(rec);
        case Balance:
            return rec->nValue;
        case MintProbability:
            return formatDayToMint(rec);
        }
        break;

      case Qt::BackgroundColorRole:
        if(rec->getAge() < 30)
        {
            return COLOR_MINT_YOUNG;
        }
        else if (rec->getAge() >= 30 && rec->getAge() < 90)
        {
            return COLOR_MINT_MATURE;
        }
        else
        {
            return COLOR_MINT_OLD;
        }
        break;

    }
    return QVariant();
}

void MintingTableModel::setMintingInterval(int interval)
{
    mintingInterval = interval;
}

QString MintingTableModel::lookupAddress(const std::string &address, bool tooltip) const
{
    QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address));
    QString description;
    if(!label.isEmpty())
    {
        description += label + QString(" ");
    }
    if(label.isEmpty() || walletModel->getOptionsModel()->getDisplayAddresses() || tooltip)
    {
        description += QString("(") + QString::fromStdString(address) + QString(")");
    }
    return description;
}

QString MintingTableModel::formatDayToMint(const KernelRecord *wtx) const
{
    const CBlockIndex *p = GetLastBlockIndex(pindexBest, true);
    double difficulty = p->GetBlockDifficulty();

    double prob = wtx->getProbToMintWithinNMinutes(difficulty, mintingInterval);
    prob = prob * 100;
    return QString::number(prob, 'f', 2) + "%";
}

QString MintingTableModel::formatTxAddress(const KernelRecord *wtx, bool tooltip) const
{
    return QString::fromStdString(wtx->address);
}

QString MintingTableModel::formatTxCoinDay(const KernelRecord *wtx) const
{
    return QString::number(wtx->coinAge);
}

QString MintingTableModel::formatTxAge(const KernelRecord *wtx) const
{
    int64 nAge = wtx->getAge();
    return QString::number(nAge);
}

QString MintingTableModel::formatTxBalance(const KernelRecord *wtx) const
{
    return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->nValue);
}

QVariant MintingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole)
        {
            return columns[section];
        }
        else if (role == Qt::TextAlignmentRole)
        {
            return column_alignments[section];
        } else if (role == Qt::ToolTipRole)
        {
            switch(section)
            {
            case Address:
                return tr("TODO");
            case Age:
                return tr("TODO");
            case Balance:
                return tr("TODO");
            case CoinDay:
                return tr("TODO");
            case MintProbability:
                return tr("TODO");
            }
        }
    }
    return QVariant();
}

QModelIndex MintingTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    KernelRecord *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

<commit_msg>Replaced hardcoded values by constants<commit_after>#include "mintingtablemodel.h"
#include "transactiontablemodel.h"
#include "guiutil.h"
#include "kernelrecord.h"
#include "guiconstants.h"
#include "transactiondesc.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "addresstablemodel.h"
#include "bitcoinunits.h"
#include "util.h"
#include "kernel.h"

#include "wallet.h"

#include <QLocale>
#include <QList>
#include <QColor>
#include <QTimer>
#include <QIcon>
#include <QDateTime>
#include <QtAlgorithms>

static int column_alignments[] = {
    Qt::AlignLeft|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter,
    Qt::AlignRight|Qt::AlignVCenter
};

struct TxLessThan
{
    bool operator()(const KernelRecord &a, const KernelRecord &b) const
    {
        return a.hash < b.hash;
    }
    bool operator()(const KernelRecord &a, const uint256 &b) const
    {
        return a.hash < b;
    }
    bool operator()(const uint256 &a, const KernelRecord &b) const
    {
        return a < b.hash;
    }
};

class MintingTablePriv
{
public:
    MintingTablePriv(CWallet *wallet, MintingTableModel *parent):
        wallet(wallet),
        parent(parent)
    {
    }
    CWallet *wallet;
    MintingTableModel *parent;

    QList<KernelRecord> cachedWallet;

    void refreshWallet()
    {
#ifdef WALLET_UPDATE_DEBUG
        qDebug() << "refreshWallet";
#endif
        cachedWallet.clear();
        {
            LOCK(wallet->cs_wallet);
            for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
            {
                QList<KernelRecord> txList = KernelRecord::decomposeOutput(wallet, it->second);
                for(QList<KernelRecord>::iterator i = txList.begin(); i != txList.end(); ++i) {
                    if(!(*i).spent) {
                        cachedWallet.append(*i);
                    }
                }

            }
        }
    }

    /* Update our model of the wallet incrementally, to synchronize our model of the wallet
       with that of the core.

       Call with list of hashes of transactions that were added, removed or changed.
     */
    void updateWallet(const QList<uint256> &updated)
    {
        // Walk through updated transactions, update model as needed.
#ifdef WALLET_UPDATE_DEBUG
        qDebug() << "updateWallet";
#endif
        // Sort update list, and iterate through it in reverse, so that model updates
        //  can be emitted from end to beginning (so that earlier updates will not influence
        // the indices of latter ones).
        QList<uint256> updated_sorted = updated;
        qSort(updated_sorted);

        {
            LOCK(wallet->cs_wallet);
            for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
            {
                const uint256 &hash = updated_sorted.at(update_idx);
                // Find transaction in wallet
                std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
                bool inWallet = mi != wallet->mapWallet.end();
                // Find bounds of this transaction in model
                QList<KernelRecord>::iterator lower = qLowerBound(
                    cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
                QList<KernelRecord>::iterator upper = qUpperBound(
                    cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
                int lowerIndex = (lower - cachedWallet.begin());
                int upperIndex = (upper - cachedWallet.begin());

                // Determine if transaction is in model already
                bool inModel = false;
                if(lower != upper)
                {
                    inModel = true;
                }

#ifdef WALLET_UPDATE_DEBUG
                qDebug() << "  " << QString::fromStdString(hash.ToString()) << inWallet << " " << inModel
                        << lowerIndex << "-" << upperIndex;
#endif

                if(inWallet && !inModel)
                {
                    // Added -- insert at the right position
                    QList<KernelRecord> toInsert =
                            KernelRecord::decomposeOutput(wallet, mi->second);
                    if(!toInsert.isEmpty()) /* only if something to insert */
                    {
                        parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
                        int insert_idx = lowerIndex;
                        foreach(const KernelRecord &rec, toInsert)
                        {
                            if(!rec.spent) {
                                cachedWallet.insert(insert_idx, rec);
                                insert_idx += 1;
                            }
                        }
                        parent->endInsertRows();
                    }
                }
                else if(!inWallet && inModel)
                {
                    // Removed -- remove entire transaction from table
                    parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
                    cachedWallet.erase(lower, upper);
                    parent->endRemoveRows();
                }
                else if(inWallet && inModel)
                {
                    // Updated -- nothing to do, status update will take care of this
                }
            }
        }
    }

    int size()
    {
        return cachedWallet.size();
    }

    KernelRecord *index(int idx)
    {
        if(idx >= 0 && idx < cachedWallet.size())
        {
            KernelRecord *rec = &cachedWallet[idx];
            return rec;
        }
        else
        {
            return 0;
        }
    }

    QString describe(KernelRecord *rec)
    {
        {
            LOCK(wallet->cs_wallet);
            std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
            if(mi != wallet->mapWallet.end())
            {
                return TransactionDesc::toHTML(wallet, mi->second);
            }
        }
        return QString("");
    }

};

MintingTableModel::MintingTableModel(CWallet *wallet, WalletModel *parent):
        QAbstractTableModel(parent),
        wallet(wallet),
        walletModel(parent),
        mintingInterval(10),
        priv(new MintingTablePriv(wallet, this))
{
    columns << tr("Address") << tr("Age") << tr("Balance") << tr("CoinDay") << tr("MintProbability");
    priv->refreshWallet();

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(MODEL_UPDATE_DELAY);
}

MintingTableModel::~MintingTableModel()
{
    delete priv;
}

void MintingTableModel::update()
{
    QList<uint256> updated;

    {
        TRY_LOCK(wallet->cs_wallet, lockWallet);
        if (lockWallet && !wallet->vWalletUpdated.empty())
        {
            BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
            {
                updated.append(hash);
            }
            wallet->vWalletUpdated.clear();
        }
    }

    if(!updated.empty())
    {
        priv->updateWallet(updated);
    }
}

int MintingTableModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return priv->size();
}

int MintingTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return columns.length();
}

QVariant MintingTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    KernelRecord *rec = static_cast<KernelRecord*>(index.internalPointer());

    switch(role)
    {
      case Qt::DisplayRole:
        switch(index.column())
        {
        case Address:
            return formatTxAddress(rec, false);
        case Age:
            return formatTxAge(rec);
        case Balance:
            return formatTxBalance(rec);
        case CoinDay:
            return formatTxCoinDay(rec);
        case MintProbability:
            return formatDayToMint(rec);
        }
        break;
      case Qt::TextAlignmentRole:
        return column_alignments[index.column()];
        break;

      case Qt::EditRole:
        switch(index.column())
        {
        case Address:
            return formatTxAddress(rec, false);
        case Age:
            return formatTxAge(rec);
        case CoinDay:
            return formatTxCoinDay(rec);
        case Balance:
            return rec->nValue;
        case MintProbability:
            return formatDayToMint(rec);
        }
        break;
      case Qt::BackgroundColorRole:
        int minAge = nStakeMinAge / 60 / 60 / 24;
        int maxAge = STAKE_MAX_AGE / 60 / 60 / 24;
        if(rec->getAge() < minAge)
        {
            return COLOR_MINT_YOUNG;
        }
        else if (rec->getAge() >= minAge && rec->getAge() < maxAge)
        {
            return COLOR_MINT_MATURE;
        }
        else
        {
            return COLOR_MINT_OLD;
        }
        break;

    }
    return QVariant();
}

void MintingTableModel::setMintingInterval(int interval)
{
    mintingInterval = interval;
}

QString MintingTableModel::lookupAddress(const std::string &address, bool tooltip) const
{
    QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address));
    QString description;
    if(!label.isEmpty())
    {
        description += label + QString(" ");
    }
    if(label.isEmpty() || walletModel->getOptionsModel()->getDisplayAddresses() || tooltip)
    {
        description += QString("(") + QString::fromStdString(address) + QString(")");
    }
    return description;
}

QString MintingTableModel::formatDayToMint(const KernelRecord *wtx) const
{
    const CBlockIndex *p = GetLastBlockIndex(pindexBest, true);
    double difficulty = p->GetBlockDifficulty();

    double prob = wtx->getProbToMintWithinNMinutes(difficulty, mintingInterval);
    prob = prob * 100;
    return QString::number(prob, 'f', 2) + "%";
}

QString MintingTableModel::formatTxAddress(const KernelRecord *wtx, bool tooltip) const
{
    return QString::fromStdString(wtx->address);
}

QString MintingTableModel::formatTxCoinDay(const KernelRecord *wtx) const
{
    return QString::number(wtx->coinAge);
}

QString MintingTableModel::formatTxAge(const KernelRecord *wtx) const
{
    int64 nAge = wtx->getAge();
    return QString::number(nAge);
}

QString MintingTableModel::formatTxBalance(const KernelRecord *wtx) const
{
    return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->nValue);
}

QVariant MintingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole)
        {
            return columns[section];
        }
        else if (role == Qt::TextAlignmentRole)
        {
            return column_alignments[section];
        } else if (role == Qt::ToolTipRole)
        {
            switch(section)
            {
            case Address:
                return tr("TODO");
            case Age:
                return tr("TODO");
            case Balance:
                return tr("TODO");
            case CoinDay:
                return tr("TODO");
            case MintProbability:
                return tr("TODO");
            }
        }
    }
    return QVariant();
}

QModelIndex MintingTableModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    KernelRecord *data = priv->index(row);
    if(data)
    {
        return createIndex(row, column, priv->index(row));
    }
    else
    {
        return QModelIndex();
    }
}

<|endoftext|>


<commit_before>#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>

#include "seqan/seq_io.h"
#include "seqan/stream.h"

#include "model.h"

using namespace std;
using namespace BamTools;

string bases = "ACGT";

typedef vector< string > SampleNames;

string get_sample(string& tag){
    string res;
    for(size_t i = 0; tag[i] != '_'; i++) {
        res.push_back(tag[i]);
    }
    return(res);
}

int find_sample_index(string s, SampleNames sv){
    for (size_t i=0; i < sv.size(); i++){
        if(s.compare(sv[i])==0){
            return i;
        }
    }
    cerr << "didn't find name " << s << endl;
    return(13); //TODO refactor this to  update sampe in place!
}

uint16_t base_index(char b){
    switch(b){
        case 'A':
        case 'a':
            return 0;
         case 'T':
         case 't':
             return 3;
         case 'C':
         case 'c':
             return 1;
         case 'G':
         case 'g':
             return 2;
         case '-':
         case 'N':
             return 4;
         default:
             cerr << "Don't know what to make of base" << b <<endl;
             return 4;
    };
}

class VariantVisitor : public PileupVisitor{
    public://TODO
        VariantVisitor(const RefVector& bam_references,
                       const seqan::FaiIndex& idx_ref,
                       SampleNames samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int q =13):

            PileupVisitor(), m_idx_ref(idx_ref), m_bam_ref(bam_references),
                             m_samples(samples), m_q(q), m_params(p), m_ali(ali)
            {
                nsamp = m_samples.size();
            }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             string chr = m_bam_ref[pileupData.RefId].RefName;
             int pos  = pileupData.Position;
             seqan::getIdByName(m_idx_ref, chr, chr_index);

             seqan::readRegion(current_base, m_idx_ref, chr_index, pos, pos+1);

             ReadDataVector bcalls (nsamp, ReadData{{ 0,0,0,0 }}); //fill constructor
             string tag_id;
             for(auto it = begin(pileupData.PileupAlignments);
                      it != end(pileupData.PileupAlignments);
                      ++it){
                 int const *pos = &it->PositionInAlignment;
                 if (it->Alignment.Qualities[*pos] - 33 > m_q){
                     it->Alignment.GetTag("RG", tag_id);
                     int sindex = find_sample_index(get_sample(tag_id), m_samples);
                     size_t bindex  = base_index(it->Alignment.AlignedBases[*pos]);
                     if (bindex > 3){
                         bcalls[sindex].reads[bindex] += 1;
                     }
                 }
            }
            ModelInput d = {"", 1, base_index(toCString(current_base)[0]), bcalls};
            double prob = TetMAProbability(m_params,d);
            if(1.0 > 0.1){
             cout << chr << '\t' << pos << '\t' << current_base << '\t' <<
                 prob << '\t' << TetMAProbOneMutation(m_params,d) << endl;
            }
        }
    private:
        seqan::FaiIndex m_idx_ref;
        RefVector m_bam_ref;
        SampleNames m_samples;
        int m_q;
        int nsamp;
        ModelParams m_params;
        BamAlignment& m_ali;
        seqan::CharString current_base;
        unsigned chr_index;

};

int main(){
    BamReader myBam;
    myBam.Open("test/scf_8254670.bam");
    RefVector references = myBam.GetReferenceData();
    cerr << "buliding fasta index..." << endl;
    seqan::FaiIndex refIndex;
    build(refIndex, "test/tt-ref.fasta");

    SampleNames all_samples {"M0", "M19", "M20", "M28","M25", "M29",
                             "M40", "M44","M47", "M50","M51", "M531"};
    ModelParams p = {
       0.001,
       {0.25, 0.25, 0.25, 0.25},
       1.0e-8,
       0.01,
       0.001,
       0.001,
    };
    BamAlignment ali;
    PileupEngine pileup;
    VariantVisitor *v = new VariantVisitor(references, refIndex, all_samples,p, ali);
    pileup.AddVisitor(v);
    while( myBam.GetNextAlignment(ali)){
        pileup.AddAlignment(ali);

    };
    pileup.Flush();
    return 0;
}

<commit_msg>Squashed bug returning only empty ReadVectors<commit_after>#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>

#include "seqan/seq_io.h"
#include "seqan/stream.h"

#include "model.h"

using namespace std;
using namespace BamTools;

string bases = "ACGT";

typedef vector< string > SampleNames;

string get_sample(string& tag){
    string res;
    for(size_t i = 0; tag[i] != '_'; i++) {
        res.push_back(tag[i]);
    }
    return(res);
}

int find_sample_index(string s, SampleNames sv){
    for (size_t i=0; i < sv.size(); i++){
        if(s.compare(sv[i])==0){
            return i;
        }
    }
    cerr << "didn't find name " << s << endl;
    return(13); //TODO refactor this to  update sampe in place!
}

uint16_t base_index(char b){
    switch(b){
        case 'A':
        case 'a':
            return 0;
         case 'T':
         case 't':
             return 3;
         case 'C':
         case 'c':
             return 1;
         case 'G':
         case 'g':
             return 2;
         case '-':
         case 'N':
             return 4;
         default:
             cerr << "Don't know what to make of base" << b <<endl;
             return 4;
    };
}

class VariantVisitor : public PileupVisitor{
    public://TODO
        VariantVisitor(const RefVector& bam_references,
                       const seqan::FaiIndex& idx_ref,
                       SampleNames samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int q =13):

            PileupVisitor(), m_idx_ref(idx_ref), m_bam_ref(bam_references),
                             m_samples(samples), m_q(q), m_params(p), m_ali(ali)
            {
                nsamp = m_samples.size();
            }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             string chr = m_bam_ref[pileupData.RefId].RefName;
             int pos  = pileupData.Position;
             seqan::getIdByName(m_idx_ref, chr, chr_index);

             seqan::readRegion(current_base, m_idx_ref, chr_index, pos, pos+1);

             ReadDataVector bcalls (nsamp, ReadData{{ 0,0,0,0 }}); //fill constructor
             string tag_id;
             for(auto it = begin(pileupData.PileupAlignments);
                      it != end(pileupData.PileupAlignments);
                      ++it){
                 int const *pos = &it->PositionInAlignment;
                 if (it->Alignment.Qualities[*pos] - 33 > m_q){
                     it->Alignment.GetTag("RG", tag_id);
                     int sindex = find_sample_index(get_sample(tag_id), m_samples);
                     size_t bindex  = base_index(it->Alignment.AlignedBases[*pos]);
                     if (bindex < 3){
                         bcalls[sindex].reads[bindex] += 1;
                     }
                 }
            }
            ModelInput d = {"", 1, base_index(toCString(current_base)[0]), bcalls};
            double prob = TetMAProbability(m_params,d);
            if(1.0 > 0.1){
             cout << chr << '\t' << pos << '\t' << current_base << '\t' <<
                 prob << '\t' << TetMAProbOneMutation(m_params,d) << endl;
            }
        }
    private:
        seqan::FaiIndex m_idx_ref;
        RefVector m_bam_ref;
        SampleNames m_samples;
        int m_q;
        int nsamp;
        ModelParams m_params;
        BamAlignment& m_ali;
        seqan::CharString current_base;
        unsigned chr_index;

};

int main(){
    BamReader myBam;
    myBam.Open("test/scf_8254670.bam");
    RefVector references = myBam.GetReferenceData();
    cerr << "buliding fasta index..." << endl;
    seqan::FaiIndex refIndex;
    build(refIndex, "test/tt-ref.fasta");

    SampleNames all_samples {"M0", "M19", "M20", "M28","M25", "M29",
                             "M40", "M44","M47", "M50","M51", "M531"};
    ModelParams p = {
       0.001,
       {0.25, 0.25, 0.25, 0.25},
       1.0e-8,
       0.01,
       0.001,
       0.001,
    };
    BamAlignment ali;
    PileupEngine pileup;
    VariantVisitor *v = new VariantVisitor(references, refIndex, all_samples,p, ali);
    pileup.AddVisitor(v);
    while( myBam.GetNextAlignment(ali)){
        pileup.AddAlignment(ali);

    };
    pileup.Flush();
    return 0;
}

<|endoftext|>