<commit_before>#include <GL/glew.h>
#define GLM_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <SDL/SDL.h>
#include <list>
#include <algorithm>
#include <functional>

#include "RenderingContext.h"
#include "scene/GraphNode.h"
#include "scene/Skybox.h"
#include "scene/Terrain.h"
#include "scene/Mech.h"
#include "animations/Animation.h"

GraphNode *scene = NULL;
RenderingContext *rc;
std::list<Animation*> animations;
int move_forward = 0;

class TestSceneRotation : public Animation
{
private:
	GraphNode* subject;

public:
	TestSceneRotation(GraphNode* subject) : subject(subject)
	{
		rotation = 0;
		y = 0;
	};

	virtual void update(float timestep)
	{
		glm::vec4 cam_pos =
			subject->getWorldCoordinates(
				glm::rotate(rotation, glm::vec3(0.0f, 1.0f, 0.0f)) *
				glm::vec4(0.0f, y, 3.0f, 1.0f));
		rc->setCamera(cam_pos.xyz(), subject);
		while (rotation > 360.0f) rotation -= 360.0f;
	};

	float y;
	float rotation;
} *scene_rot;

class MechWalk : public Animation
{
private:
	Mech* subject;
	Terrain* terrain;

public:
	MechWalk(Mech* subject, Terrain* terrain) : subject(subject), terrain(terrain) {};

	virtual void update(float timestep)
	{
		glm::vec4 current_pos = subject->getWorldCoordinates();
		current_pos.z += move_forward * timestep;
		glm::vec3 new_pos(current_pos.x, terrain->getHeight(current_pos.x, current_pos.z) + 1.5f, current_pos.z);
		subject->setPosition(new_pos.x, new_pos.y, new_pos.z);
	}
};

void reshape(int width, int height)
{
	glViewport(0, 0, (GLint) width, (GLint) height);
	rc->reshape(width, height);
}

/// Sets up rendering and creates the initial scene graph.
void init_scene()
{
	static GLfloat pos[4] =
	{3000.0, 1000.0, -3000.0, 0.0};
	glLightfv(GL_LIGHT0, GL_POSITION, pos);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_TEXTURE_2D);
	//glEnable(GL_MULTISAMPLE);

	scene = new GraphNode;
	scene->addMember(new Skybox);

	Mech *mech = new Mech();
	scene->addMember(mech);
	//mech->setVisibility(false);

	Terrain *terrain = new Terrain("textures/heightmap.bmp", 20.0f);
	scene->addMember(terrain);

	rc = new RenderingContext(scene);
	rc->setCamera(glm::vec3(0.0f, 1.0f, -3.0f), mech);

	scene_rot = new TestSceneRotation(mech);
	animations.push_back(scene_rot);
	animations.push_back(new MechWalk(mech, terrain));
}

/// Sets up a new frame and renders the scene.
void draw_scene()
{
	rc->update();
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
		puts((const char*)gluErrorString(error));
}

/// Updates scene state
void update_scene(float timestep)
{
	std::for_each(
			animations.begin(),
			animations.end(),
			std::bind2nd(std::mem_fun(&Animation::update), timestep));
}

int main(int argc, char const *argv[])
{
	SDL_Surface *screen;
	Uint8 *keys;

	if (0 != SDL_Init(SDL_INIT_EVERYTHING)) return 1;

	// Do we have a joystick?
	printf("%i joysticks were found.\n", SDL_NumJoysticks() );
	for (int i=0; i < SDL_NumJoysticks(); i++)
	{
		printf("    %s\n", SDL_JoystickName(i));
	}

	// Set up an OpenGL window
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	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_ALPHA_SIZE, 8);
	//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 1);
	screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL|SDL_RESIZABLE);
	if ( ! screen ) {
		puts(SDL_GetError());
		SDL_Quit();
		exit(2);
	}
	SDL_WM_SetCaption("Mech", "mech");
	glewInit();
	printf("OpenGL version: %s\n", glGetString(GL_VERSION));
	init_scene();
	reshape(screen->w, screen->h);

	Uint32 previous_ticks = SDL_GetTicks();
	Uint32 fps_prev_t = previous_ticks, frames = 0;

	int done = 0;
	SDL_Event event;
	while (!done) {
		while (SDL_PollEvent(&event)) {
			switch(event.type) {
				case SDL_VIDEORESIZE:
					screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,
							SDL_OPENGL|SDL_RESIZABLE);
					if (screen)
						reshape(screen->w, screen->h);
					break;

				case SDL_MOUSEMOTION:
					scene_rot->y = 4.0f * (float)(event.motion.y) / (float)(screen->h) - 2.0f;
					scene_rot->rotation = -360.0f * (float)(event.motion.x) / (float)(screen->w);
					break;

				case SDL_QUIT:
					done = 1;
					break;
			}
		}
		keys = SDL_GetKeyState(NULL);

		if (keys[SDLK_ESCAPE]) {
			done = 1;
		}

		if (keys[SDLK_w])
			move_forward = 1;
		else if (keys[SDLK_s])
			move_forward = -1;
		else
			move_forward = 0;

		// update
		Uint32 t = SDL_GetTicks();
		update_scene((float)(t - previous_ticks) / 1000.0f);
		previous_ticks = t;

		// count FPS
		frames++;
		if (fps_prev_t + 5000 < t) {
			printf("FPS: %f\n", (float)frames / ((float)(t - fps_prev_t) / 1000.0f));
			fps_prev_t = t;
			frames = 0;
		}

		// render
		draw_scene();
	}
	SDL_Quit();
	delete scene;
	return 0;
}
<commit_msg>MSAA as an option.<commit_after>#include <GL/glew.h>
#define GLM_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <SDL/SDL.h>
#include <list>
#include <algorithm>
#include <functional>

#include "RenderingContext.h"
#include "scene/GraphNode.h"
#include "scene/Skybox.h"
#include "scene/Terrain.h"
#include "scene/Mech.h"
#include "animations/Animation.h"

GraphNode *scene = NULL;
RenderingContext *rc;
std::list<Animation*> animations;
int move_forward = 0;

class TestSceneRotation : public Animation
{
private:
	GraphNode* subject;

public:
	TestSceneRotation(GraphNode* subject) : subject(subject)
	{
		rotation = 0;
		y = 0;
	};

	virtual void update(float timestep)
	{
		glm::vec4 cam_pos =
			subject->getWorldCoordinates(
				glm::rotate(rotation, glm::vec3(0.0f, 1.0f, 0.0f)) *
				glm::vec4(0.0f, y, 3.0f, 1.0f));
		rc->setCamera(cam_pos.xyz(), subject);
		while (rotation > 360.0f) rotation -= 360.0f;
	};

	float y;
	float rotation;
} *scene_rot;

class MechWalk : public Animation
{
private:
	Mech* subject;
	Terrain* terrain;

public:
	MechWalk(Mech* subject, Terrain* terrain) : subject(subject), terrain(terrain) {};

	virtual void update(float timestep)
	{
		glm::vec4 current_pos = subject->getWorldCoordinates();
		current_pos.z += move_forward * timestep;
		glm::vec3 new_pos(current_pos.x, terrain->getHeight(current_pos.x, current_pos.z) + 1.5f, current_pos.z);
		subject->setPosition(new_pos.x, new_pos.y, new_pos.z);
	}
};

void reshape(int width, int height)
{
	glViewport(0, 0, (GLint) width, (GLint) height);
	rc->reshape(width, height);
}

/// Sets up rendering and creates the initial scene graph.
void init_scene()
{
	static GLfloat pos[4] =
	{3000.0, 1000.0, -3000.0, 0.0};
	glLightfv(GL_LIGHT0, GL_POSITION, pos);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_TEXTURE_2D);
	//glEnable(GL_MULTISAMPLE);

	scene = new GraphNode;
	scene->addMember(new Skybox);

	Mech *mech = new Mech();
	scene->addMember(mech);
	//mech->setVisibility(false);

	Terrain *terrain = new Terrain("textures/heightmap.bmp", 20.0f);
	scene->addMember(terrain);

	rc = new RenderingContext(scene);
	rc->setCamera(glm::vec3(0.0f, 1.0f, -3.0f), mech);

	scene_rot = new TestSceneRotation(mech);
	animations.push_back(scene_rot);
	animations.push_back(new MechWalk(mech, terrain));
}

/// Sets up a new frame and renders the scene.
void draw_scene()
{
	rc->update();
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
		puts((const char*)gluErrorString(error));
}

/// Updates scene state
void update_scene(float timestep)
{
	std::for_each(
			animations.begin(),
			animations.end(),
			std::bind2nd(std::mem_fun(&Animation::update), timestep));
}

int main(int argc, char const *argv[])
{
	bool conf_enable_msaa = false;
	SDL_Surface *screen;
	Uint8 *keys;

	if (0 != SDL_Init(SDL_INIT_EVERYTHING)) return 1;

	// Do we have a joystick?
	printf("%i joysticks were found.\n", SDL_NumJoysticks() );
	for (int i=0; i < SDL_NumJoysticks(); i++)
	{
		printf("    %s\n", SDL_JoystickName(i));
	}

	// Set up an OpenGL window
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	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_ALPHA_SIZE, 8);

	if (conf_enable_msaa) {
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
	}
	screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL|SDL_RESIZABLE);
	if ( ! screen ) {
		puts(SDL_GetError());
		SDL_Quit();
		exit(2);
	}
	SDL_WM_SetCaption("Mech", "mech");
	glewInit();
	printf("OpenGL version: %s\n", glGetString(GL_VERSION));
	init_scene();
	reshape(screen->w, screen->h);

	Uint32 previous_ticks = SDL_GetTicks();
	Uint32 fps_prev_t = previous_ticks, frames = 0;

	int done = 0;
	SDL_Event event;
	while (!done) {
		while (SDL_PollEvent(&event)) {
			switch(event.type) {
				case SDL_VIDEORESIZE:
					screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,
							SDL_OPENGL|SDL_RESIZABLE);
					if (screen)
						reshape(screen->w, screen->h);
					break;

				case SDL_MOUSEMOTION:
					scene_rot->y = 4.0f * (float)(event.motion.y) / (float)(screen->h) - 2.0f;
					scene_rot->rotation = -360.0f * (float)(event.motion.x) / (float)(screen->w);
					break;

				case SDL_QUIT:
					done = 1;
					break;
			}
		}
		keys = SDL_GetKeyState(NULL);

		if (keys[SDLK_ESCAPE]) {
			done = 1;
		}

		if (keys[SDLK_w])
			move_forward = 1;
		else if (keys[SDLK_s])
			move_forward = -1;
		else
			move_forward = 0;

		// update
		Uint32 t = SDL_GetTicks();
		update_scene((float)(t - previous_ticks) / 1000.0f);
		previous_ticks = t;

		// count FPS
		frames++;
		if (fps_prev_t + 5000 < t) {
			printf("FPS: %f\n", (float)frames / ((float)(t - fps_prev_t) / 1000.0f));
			fps_prev_t = t;
			frames = 0;
		}

		// render
		draw_scene();
	}
	SDL_Quit();
	delete scene;
	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>
#include <sys/stat.h>

#include "boost/program_options.hpp"
#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include "utils/bamtools_fasta.h"

#include "model.h"
#include "parsers.h"

using namespace std;
using namespace BamTools;

class VariantVisitor : public PileupVisitor{
    public:
        VariantVisitor(const RefVector& bam_references,
                       const SamHeader& header,
                       const Fasta& idx_ref,
                       ostream *out_stream,
                       const SampleMap& samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int qual_cut,
                       int mapping_cut,
                       double prob_cut):

            PileupVisitor(), m_idx_ref(idx_ref), m_bam_ref(bam_references),
                             m_header(header), m_samples(samples),
                             m_qual_cut(qual_cut), m_params(p), m_ali(ali),
                             m_ostream(out_stream), m_prob_cut(prob_cut),
                             m_mapping_cut(mapping_cut)
                              { }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             uint64_t pos  = pileupData.Position;
             m_idx_ref.GetBase(pileupData.RefId, pos, current_base);
             ReadDataVector bcalls (m_samples.size(), ReadData{{ 0,0,0,0 }});
             for(auto it = begin(pileupData.PileupAlignments);
                      it !=  end(pileupData.PileupAlignments);
                      ++it){
                 if( include_site(*it, m_mapping_cut, m_qual_cut) ){
                    it->Alignment.GetTag("RG", tag_id);
                    uint32_t sindex = m_samples[tag_id]; //TODO check samples existed!
                    uint16_t bindex  = base_index(it->Alignment.QueryBases[it->PositionInAlignment]);
                    if (bindex < 4 ){
                        bcalls[sindex].reads[bindex] += 1;
                    }
                }
            }
            uint16_t ref_base_idx = base_index(current_base);
            if (ref_base_idx < 4  ){ //TODO Model for bases at which reference is 'N'
                ModelInput d = {ref_base_idx, bcalls};
                double prob_one = TetMAProbOneMutation(m_params,d);
                double prob = TetMAProbability(m_params, d);
                if(prob >= m_prob_cut){
                     *m_ostream << m_bam_ref[pileupData.RefId].RefName << '\t'
                                << pos << '\t'
                                << current_base << '\t'
                                << prob << '\t'
                                << prob_one << '\t'
                                << endl;
                }
            }
         }
    private:
        RefVector m_bam_ref;
        SamHeader m_header;
        Fasta m_idx_ref;
        ostream* m_ostream;
        SampleMap m_samples;
        BamAlignment& m_ali;
        ModelParams m_params;
        int m_qual_cut;
        int m_mapping_cut;
        double m_prob_cut;
        char current_base;
        string tag_id;
        uint64_t chr_index;
};

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

    namespace po = boost::program_options;
    string ref_file;
    string config_path;
    po::options_description cmd("Command line options");
    cmd.add_options()
        ("help,h", "Print a help message")
        ("bam,b", po::value<string>()->required(), "Path to BAM file")
        ("bam-index,x", po::value<string>()->default_value(""), "Path to BAM index, (defalult is <bam_path>.bai")
        ("reference,r", po::value<string>(&ref_file)->required(),  "Path to reference genome")
//       ("ancestor,a", po::value<string>(&anc_tag), "Ancestor RG sample ID")
//        ("sample-name,s", po::value<vector <string> >()->required(), "Sample tags")
        ("qual,q", po::value<int>()->default_value(13),
                   "Base quality cuttoff")

        ("mapping-qual,m", po::value<int>()->default_value(13),
                    "Mapping quality cuttoff")

        ("prob,p", po::value<double>()->default_value(0.1),
                   "Mutaton probability cut-off")
        ("out,o", po::value<string>()->default_value("acuMUlate_result.tsv"),
                    "Out file name")
        ("intervals,i", po::value<string>(), "Path to bed file")
        ("config,c", po::value<string>(), "Path to config file")
        ("theta", po::value<double>()->required(), "theta")
        ("nfreqs", po::value<vector<double> >()->multitoken(), "")
        ("mu", po::value<double>()->required(), "")
        ("seq-error", po::value<double>()->required(), "")
        ("phi-haploid",     po::value<double>()->required(), "")
        ("phi-diploid",     po::value<double>()->required(), "");

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, cmd), vm);

    if (vm.count("help")){
        cout << cmd << endl;
        return 0;
    }

    if (vm.count("config")){
        ifstream config_stream (vm["config"].as<string>());
        po::store(po::parse_config_file(config_stream, cmd, false), vm);
    }

    vm.notify();
    ModelParams params = {
        vm["theta"].as<double>(),
        vm["nfreqs"].as<vector< double> >(),
        vm["mu"].as<double>(),
        vm["seq-error"].as<double>(),
        vm["phi-haploid"].as<double>(),
        vm["phi-diploid"].as<double>(),
    };
    string bam_path = vm["bam"].as<string>();
    string index_path = vm["bam-index"].as<string>();
    if(index_path == ""){
        index_path = bam_path + ".bai";
    }

    ofstream result_stream (vm["out"].as<string>());
    // Start setiing up files
    //TODO: check sucsess of all these opens/reads:

    BamReader experiment;
    experiment.Open(bam_path);
    experiment.OpenIndex(index_path);
    RefVector references = experiment.GetReferenceData();
    SamHeader header = experiment.GetHeader();

    //Fasta reference
    Fasta reference_genome; // BamTools::Fasta
    struct stat file_info;
    string faidx_path = ref_file + ".fai";
    if (stat(faidx_path.c_str(), &file_info) != 0){
        reference_genome.CreateIndex(faidx_path);
    }
    reference_genome.Open(faidx_path, faidx_path);

    // Map readgroups to samples
    // TODO: this presumes first sample is ancestor. True for our data, not for
    // others.
    // First map all sample names to an index for ReadDataVectors
    SampleMap name_map;
    uint16_t sindex = 0;
    for(auto it = header.ReadGroups.Begin(); it!= header.ReadGroups.End(); it++){
        if(it->HasSample()){
            auto s  = name_map.find(it->Sample);
            if( s == name_map.end()){ // not in there yet
                name_map[it->Sample] = sindex;
                sindex += 1;
            }
        }
    }
    // And now, go back over the read groups to map RG:sample index
    SampleMap samples;
    for(auto it = header.ReadGroups.Begin(); it!= header.ReadGroups.End(); it++){
        if(it->HasSample()){
            samples[it->ID] = name_map[it->Sample];
        }
    }

    PileupEngine pileup;
    BamAlignment ali;

    VariantVisitor *v = new VariantVisitor(
            references,
            header,
            reference_genome,
            &result_stream,
//            vm["sample-name"].as<vector< string> >(),
            samples,
            params,
            ali,
            vm["qual"].as<int>(),
            vm["mapping-qual"].as<int>(),
            vm["prob"].as<double>()
        );
    pileup.AddVisitor(v);

    if (vm.count("intervals")){
        BedFile bed (vm["intervals"].as<string>());
        BedInterval region;
        while(bed.get_interval(region) == 0){
            int ref_id = experiment.GetReferenceID(region.chr);
            experiment.SetRegion(ref_id, region.start, ref_id, region.end);
            while( experiment.GetNextAlignment(ali) ){
                pileup.AddAlignment(ali);
            }
        }
    }
    else{
        while( experiment.GetNextAlignment(ali)){
            pileup.AddAlignment(ali);
        }
    }
    pileup.Flush();
    return 0;
}

<commit_msg>bug in specification of ref path<commit_after>#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>
#include <sys/stat.h>

#include "boost/program_options.hpp"
#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include "utils/bamtools_fasta.h"

#include "model.h"
#include "parsers.h"

using namespace std;
using namespace BamTools;

class VariantVisitor : public PileupVisitor{
    public:
        VariantVisitor(const RefVector& bam_references,
                       const SamHeader& header,
                       const Fasta& idx_ref,
                       ostream *out_stream,
                       const SampleMap& samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int qual_cut,
                       int mapping_cut,
                       double prob_cut):

            PileupVisitor(), m_idx_ref(idx_ref), m_bam_ref(bam_references),
                             m_header(header), m_samples(samples),
                             m_qual_cut(qual_cut), m_params(p), m_ali(ali),
                             m_ostream(out_stream), m_prob_cut(prob_cut),
                             m_mapping_cut(mapping_cut)
                              { }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             uint64_t pos  = pileupData.Position;
             m_idx_ref.GetBase(pileupData.RefId, pos, current_base);
             ReadDataVector bcalls (m_samples.size(), ReadData{{ 0,0,0,0 }});
             for(auto it = begin(pileupData.PileupAlignments);
                      it !=  end(pileupData.PileupAlignments);
                      ++it){
                 if( include_site(*it, m_mapping_cut, m_qual_cut) ){
                    it->Alignment.GetTag("RG", tag_id);
                    uint32_t sindex = m_samples[tag_id]; //TODO check samples existed!
                    uint16_t bindex  = base_index(it->Alignment.QueryBases[it->PositionInAlignment]);
                    if (bindex < 4 ){
                        bcalls[sindex].reads[bindex] += 1;
                    }
                }
            }
            uint16_t ref_base_idx = base_index(current_base);
            if (ref_base_idx < 4  ){ //TODO Model for bases at which reference is 'N'
                ModelInput d = {ref_base_idx, bcalls};
                double prob_one = TetMAProbOneMutation(m_params,d);
                double prob = TetMAProbability(m_params, d);
                if(prob >= m_prob_cut){
                     *m_ostream << m_bam_ref[pileupData.RefId].RefName << '\t'
                                << pos << '\t'
                                << current_base << '\t'
                                << prob << '\t'
                                << prob_one << '\t'
                                << endl;
                }
            }
         }
    private:
        RefVector m_bam_ref;
        SamHeader m_header;
        Fasta m_idx_ref;
        ostream* m_ostream;
        SampleMap m_samples;
        BamAlignment& m_ali;
        ModelParams m_params;
        int m_qual_cut;
        int m_mapping_cut;
        double m_prob_cut;
        char current_base;
        string tag_id;
        uint64_t chr_index;
};

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

    namespace po = boost::program_options;
    string ref_file;
    string config_path;
    po::options_description cmd("Command line options");
    cmd.add_options()
        ("help,h", "Print a help message")
        ("bam,b", po::value<string>()->required(), "Path to BAM file")
        ("bam-index,x", po::value<string>()->default_value(""), "Path to BAM index, (defalult is <bam_path>.bai")
        ("reference,r", po::value<string>(&ref_file)->required(),  "Path to reference genome")
//       ("ancestor,a", po::value<string>(&anc_tag), "Ancestor RG sample ID")
//        ("sample-name,s", po::value<vector <string> >()->required(), "Sample tags")
        ("qual,q", po::value<int>()->default_value(13),
                   "Base quality cuttoff")

        ("mapping-qual,m", po::value<int>()->default_value(13),
                    "Mapping quality cuttoff")

        ("prob,p", po::value<double>()->default_value(0.1),
                   "Mutaton probability cut-off")
        ("out,o", po::value<string>()->default_value("acuMUlate_result.tsv"),
                    "Out file name")
        ("intervals,i", po::value<string>(), "Path to bed file")
        ("config,c", po::value<string>(), "Path to config file")
        ("theta", po::value<double>()->required(), "theta")
        ("nfreqs", po::value<vector<double> >()->multitoken(), "")
        ("mu", po::value<double>()->required(), "")
        ("seq-error", po::value<double>()->required(), "")
        ("phi-haploid",     po::value<double>()->required(), "")
        ("phi-diploid",     po::value<double>()->required(), "");

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, cmd), vm);

    if (vm.count("help")){
        cout << cmd << endl;
        return 0;
    }

    if (vm.count("config")){
        ifstream config_stream (vm["config"].as<string>());
        po::store(po::parse_config_file(config_stream, cmd, false), vm);
    }

    vm.notify();
    ModelParams params = {
        vm["theta"].as<double>(),
        vm["nfreqs"].as<vector< double> >(),
        vm["mu"].as<double>(),
        vm["seq-error"].as<double>(),
        vm["phi-haploid"].as<double>(),
        vm["phi-diploid"].as<double>(),
    };
    string bam_path = vm["bam"].as<string>();
    string index_path = vm["bam-index"].as<string>();
    if(index_path == ""){
        index_path = bam_path + ".bai";
    }

    ofstream result_stream (vm["out"].as<string>());
    // Start setiing up files
    //TODO: check sucsess of all these opens/reads:

    BamReader experiment;
    experiment.Open(bam_path);
    experiment.OpenIndex(index_path);
    RefVector references = experiment.GetReferenceData();
    SamHeader header = experiment.GetHeader();

    //Fasta reference
    Fasta reference_genome; // BamTools::Fasta
    struct stat file_info;
    string faidx_path = ref_file + ".fai";
    if (stat(faidx_path.c_str(), &file_info) != 0){
        reference_genome.CreateIndex(faidx_path);
    }
    reference_genome.Open(ref_file, faidx_path);

    // Map readgroups to samples
    // TODO: this presumes first sample is ancestor. True for our data, not for
    // others.
    // First map all sample names to an index for ReadDataVectors
    SampleMap name_map;
    uint16_t sindex = 0;
    for(auto it = header.ReadGroups.Begin(); it!= header.ReadGroups.End(); it++){
        if(it->HasSample()){
            auto s  = name_map.find(it->Sample);
            if( s == name_map.end()){ // not in there yet
                name_map[it->Sample] = sindex;
                sindex += 1;
            }
        }
    }
    // And now, go back over the read groups to map RG:sample index
    SampleMap samples;
    for(auto it = header.ReadGroups.Begin(); it!= header.ReadGroups.End(); it++){
        if(it->HasSample()){
            samples[it->ID] = name_map[it->Sample];
        }
    }

    PileupEngine pileup;
    BamAlignment ali;

    VariantVisitor *v = new VariantVisitor(
            references,
            header,
            reference_genome,
            &result_stream,
//            vm["sample-name"].as<vector< string> >(),
            samples,
            params,
            ali,
            vm["qual"].as<int>(),
            vm["mapping-qual"].as<int>(),
            vm["prob"].as<double>()
        );
    pileup.AddVisitor(v);

    if (vm.count("intervals")){
        BedFile bed (vm["intervals"].as<string>());
        BedInterval region;
        while(bed.get_interval(region) == 0){
            int ref_id = experiment.GetReferenceID(region.chr);
            experiment.SetRegion(ref_id, region.start, ref_id, region.end);
            while( experiment.GetNextAlignment(ali) ){
                pileup.AddAlignment(ali);
            }
        }
    }
    else{
        while( experiment.GetNextAlignment(ali)){
            pileup.AddAlignment(ali);
        }
    }
    pileup.Flush();
    return 0;
}

<|endoftext|>


<commit_before>#include<iostream>
#include<memory>
#include<vector>
#include<bitset>
#include<unordered_map>
class CPU
{
    public:
        enum Reg {A, X, Y, PC, S};
        enum Flag {Carry, Zero, Int_Disable, Dec_Mode, Break, Overflow, Negative};
        std::unordered_map<Reg, int> regs;
        std::bitset<30> pins;
        std::bitset<8> flags;
        unsigned char int_memory[2048];
        int cycle;
        int clocks_remain;
        CPU()
        {
            // Initial state from https://wiki.nesdev.com/w/index.php/CPU_power_up_state
            regs[Reg::A] = 0;
            regs[Reg::X] = 0;
            regs[Reg::Y] = 0;
            regs[Reg::S] = 0xFD;
            regs[Reg::PC] = 0x0;
            cycle = 0;
            clocks_remain = 0;
        }

        void update_lda_flags()
        {
            if (regs[Reg::A] == 0)
            {
                flags[Flag::Zero] = 1;
            }
            if(std::bitset<8>(regs[Reg::A])[7] == 1)
            {
                flags[Flag::Negative] = 1;
            }
        }

        void update_adc_flags(unsigned int result)
        {
            flags[Flag::Carry] = result > 0xFF;
            flags[Flag::Zero] = regs[Reg::A]== 0;
            flags[Flag::Overflow] = ~(regs[Reg::A] ^ read_memory(regs[Reg::PC] + 1)) & (regs[Reg::A] ^ result) & 0x80; // ???
            flags[Flag::Negative] = std::bitset<8>(regs[Reg::A])[7] == 1;
        }

        void do_cycle()
        {
            clocks_remain--;
            std::cout << "Doing cycle: " << cycle << std::endl;
            std::cout << "Clocks remaining: " << clocks_remain << std::endl;
            auto opcode = read_memory(regs[Reg::PC]);
            switch(opcode)
            {
                case 0xA9: // LDA IMMEDIATE
                    if(clocks_remain < 0)
                        clocks_remain = 1;
                    if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory(regs[Reg::PC] + 1);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xA5: // LDA ZERO PAGE
                    if(clocks_remain < 0)
                        clocks_remain = 2;
                    if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory(read_memory(regs[Reg::PC] + 1));
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }

                    break;
                case 0xB5: // LDA ZERO PAGE,X
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory((read_memory(regs[Reg::PC]+1) + regs[Reg::X]) % 255);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xAD: // LDA ABSOLUTE
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xBD: // LDA ABSOLUTE,X
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        if((absolute/256) < (absolute+regs[Reg::X])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1)) + regs[Reg::X];
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xB9: // LDA ABSOLUTE,Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        if((absolute/256) < (absolute+regs[Reg::Y])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1)) + regs[Reg::Y];
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xA1: // LDA (INDIRECT,X)
                    if(clocks_remain < 0)
                        clocks_remain = 5;
                    if(clocks_remain == 0)
                    {
                        unsigned short address = get_indirect_x_address();
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xB1: // LDA (INDIRECT), Y
                    if(clocks_remain < 0)
                    {
                        unsigned short address = get_address_from_zp();
                        if(address/256 < (address + regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 5;
                        else
                            clocks_remain = 4;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short zp_address = read_memory(regs[Reg::PC] + 1);
                        unsigned short address = (read_memory(zp_address + 1) << 8) + (read_memory(zp_address)); // Address _before_ Y is added
                        regs[Reg::A] = read_memory(address + regs[Reg::Y]);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0x69: // ADC IMMEDIATE
                    if(clocks_remain < 0)
                        clocks_remain = 1;
                    if(clocks_remain == 0)
                    {
                        // From http://stackoverflow.com/questions/29193303/6502-emulation-proper-way-to-implement-adc-and-sbc
                        unsigned int result = regs[Reg::A] + read_memory(regs[Reg::PC] + 1) + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x65: // ADC ZERO PAGE
                    if(clocks_remain < 0)
                        clocks_remain = 2;
                    if(clocks_remain == 0)
                    {
                        unsigned char arg = read_memory(read_memory(regs[Reg::PC] + 1));
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x75: // ADC ZERO PAGE, X
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    if(clocks_remain == 0)
                    {
                        unsigned char arg = read_memory((read_memory(regs[Reg::PC]+1) + regs[Reg::X]) % 255);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x6D: // ADC ABSOLUTE
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x7D: // ADC ABSOLUTE,X
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        if((absolute/256) < (absolute+regs[Reg::X])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1)) + regs[Reg::X];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x79: // ADC ABSOLUTE,Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
                        if((absolute/256) < (absolute+regs[Reg::Y])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short address = (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1)) + regs[Reg::Y];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x61: // ADC (INDIRECT,X)
                    if(clocks_remain < 0)
                        clocks_remain = 5;
                    if(clocks_remain == 0)
                    {
                        unsigned short address = get_indirect_x_address();
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x71: // ADC (INDIRECT), Y
                    if(clocks_remain < 0)
                    {
                        unsigned short address = get_address_from_zp(); // _before_ Y added
                        if(address/256 < (address + regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 5;
                        else
                            clocks_remain = 4;
                    }
                    if(clocks_remain == 0)
                    {
                        unsigned short address = get_address_from_zp() + regs[Reg::Y];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
            }
            cycle++;
        }

        unsigned short get_indirect_x_address()
        {
            unsigned short zp_address = (read_memory(regs[Reg::PC] + 1) + regs[Reg::X]) % 255; // Address stored in zero page to be read from
            return (read_memory(zp_address + 1) << 8) + (read_memory(zp_address));
        }

        unsigned short get_address_from_zp() // For (INDIRECT),Y addressing
        {
            unsigned short zp_address = read_memory(regs[Reg::PC] + 1);
            return (read_memory(zp_address + 1) << 8) + (read_memory(zp_address));
        }

        unsigned char read_memory(int address)
        {
            if(address < 2048)
            {
                std::cout << "Reading memory from 0x" << std::hex << address << ": got 0x" << (int)int_memory[address] << std::dec << std::endl;
                return int_memory[address];
            }
            else
                return 0;
        }
};

int main()
{
    CPU cpu = CPU();
    cpu.regs[CPU::Reg::A] = 0x1;
    cpu.regs[CPU::Reg::Y] = 0x4;
    cpu.int_memory[0] = 0x71;
    cpu.int_memory[1] = 0x1;
    cpu.int_memory[2] = 0x01;
    cpu.int_memory[0x105] = 0xBD;
    while(cpu.cycle < 10)
    {
        cpu.do_cycle();
    }
}
<commit_msg>Implement AND<commit_after>#include<iostream>
#include<memory>
#include<vector>
#include<bitset>
#include<unordered_map>
class CPU
{
    public:
        enum Reg {A, X, Y, PC, S};
        enum Flag {Carry, Zero, Int_Disable, Dec_Mode, Break, Overflow, Negative};
        std::unordered_map<Reg, int> regs;
        std::bitset<30> pins;
        std::bitset<8> flags;
        unsigned char int_memory[2048];
        int cycle;
        int clocks_remain;
        CPU()
        {
            // Initial state from https://wiki.nesdev.com/w/index.php/CPU_power_up_state
            regs[Reg::A] = 0;
            regs[Reg::X] = 0;
            regs[Reg::Y] = 0;
            regs[Reg::S] = 0xFD;
            regs[Reg::PC] = 0x0;
            cycle = 0;
            clocks_remain = 0;
        }

        void update_lda_flags()
        {
            flags[Flag::Zero] = regs[Reg::A] == 0;
            flags[Flag::Negative] = std::bitset<8>(regs[Reg::A])[7] == 1;

        }

        void update_adc_flags(unsigned int result)
        {
            flags[Flag::Carry] = result > 0xFF;
            flags[Flag::Zero] = regs[Reg::A]== 0;
            flags[Flag::Overflow] = ~(regs[Reg::A] ^ read_memory(regs[Reg::PC] + 1)) & (regs[Reg::A] ^ result) & 0x80; // ???
            flags[Flag::Negative] = std::bitset<8>(regs[Reg::A])[7] == 1;
        }

        void update_and_flags()
        {
            flags[Flag::Zero] = regs[Reg::A] == 0;
            flags[Flag::Negative] = std::bitset<8>(regs[Reg::A])[7] == 1;
        }

        void do_cycle()
        {
            clocks_remain--;
            std::cout << "Doing cycle: " << cycle << std::endl;
            std::cout << "Clocks remaining: " << clocks_remain << std::endl;
            auto opcode = read_memory(regs[Reg::PC]);
            switch(opcode)
            {
                case 0xA9: // LDA IMMEDIATE
                    if(clocks_remain < 0)
                        clocks_remain = 1;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory(regs[Reg::PC] + 1);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xA5: // LDA ZERO PAGE
                    if(clocks_remain < 0)
                        clocks_remain = 2;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory(read_memory(regs[Reg::PC] + 1));
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }

                    break;
                case 0xB5: // LDA ZERO PAGE,X
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = read_memory((read_memory(regs[Reg::PC]+1) + regs[Reg::X]) % 255);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xAD: // LDA ABSOLUTE
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address()
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xBD: // LDA ABSOLUTE,X
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if((absolute/256) < (absolute+regs[Reg::X])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::X];
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xB9: // LDA ABSOLUTE,Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if((absolute/256) < (absolute+regs[Reg::Y])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::Y];
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 3;
                        update_lda_flags();
                    }
                    break;
                case 0xA1: // LDA (INDIRECT,X)
                    if(clocks_remain < 0)
                        clocks_remain = 5;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_indirect_x_address();
                        regs[Reg::A] = read_memory(address);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0xB1: // LDA (INDIRECT),Y
                    if(clocks_remain < 0)
                    {
                        unsigned short address = get_address_from_zp();
                        if(address/256 < (address + regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 5;
                        else
                            clocks_remain = 4;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short zp_address = read_memory(regs[Reg::PC] + 1);
                        unsigned short address = (read_memory(zp_address + 1) << 8) + (read_memory(zp_address)); // Address _before_ Y is added
                        regs[Reg::A] = read_memory(address + regs[Reg::Y]);
                        regs[Reg::PC] += 2;
                        update_lda_flags();
                    }
                    break;
                case 0x69: // ADC IMMEDIATE
                    if(clocks_remain < 0)
                        clocks_remain = 1;
                    else if(clocks_remain == 0)
                    {
                        // From http://stackoverflow.com/questions/29193303/6502-emulation-proper-way-to-implement-adc-and-sbc
                        unsigned int result = regs[Reg::A] + read_memory(regs[Reg::PC] + 1) + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x65: // ADC ZERO PAGE
                    if(clocks_remain < 0)
                        clocks_remain = 2;
                    else if(clocks_remain == 0)
                    {
                        unsigned char arg = read_memory(read_memory(regs[Reg::PC] + 1));
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x75: // ADC ZERO PAGE, X
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        unsigned char arg = read_memory((read_memory(regs[Reg::PC]+1) + regs[Reg::X]) % 255);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x6D: // ADC ABSOLUTE
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address();
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x7D: // ADC ABSOLUTE,X
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if((absolute/256) < (absolute+regs[Reg::X])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::X];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x79: // ADC ABSOLUTE,Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if((absolute/256) < (absolute+regs[Reg::Y])/256) // Crossed a page boundary
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::Y];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 3;
                        update_adc_flags(result);
                    }
                    break;
                case 0x61: // ADC (INDIRECT,X)
                    if(clocks_remain < 0)
                        clocks_remain = 5;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_indirect_x_address();
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x71: // ADC (INDIRECT),Y
                    if(clocks_remain < 0)
                    {
                        unsigned short address = get_address_from_zp(); // _before_ Y added
                        if(address/256 < (address + regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 5;
                        else
                            clocks_remain = 4;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_address_from_zp() + regs[Reg::Y];
                        unsigned char arg = read_memory(address);
                        unsigned int result = regs[Reg::A] + arg + flags[Flag::Carry];
                        regs[Reg::A] = result % 255;
                        regs[Reg::PC] += 2;
                        update_adc_flags(result);
                    }
                    break;
                case 0x29: // AND IMMEDIATE
                    if(clocks_remain < 0)
                        clocks_remain = 1;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = regs[Reg::A] & read_memory(regs[Reg::PC] + 1);
                        regs[Reg::PC] += 2;
                        update_and_flags();
                    }
                    break;
                case 0x25: // AND ZERO PAGE
                    if(clocks_remain < 0)
                        clocks_remain = 2;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = regs[Reg::A] & read_memory(read_memory(regs[Reg::PC] + 1));
                        regs[Reg::PC] += 2;
                        update_and_flags();
                    }
                    break;
                case 0x35: // AND ZERO PAGE, 0x
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        regs[Reg::A] = regs[Reg::A] & read_memory((read_memory(regs[Reg::PC]+1) + regs[Reg::X]) % 255);
                        regs[Reg::PC] += 2;
                        update_and_flags();
                    }
                    break;
                case 0x2D: // AND ABSOLUTE
                    if(clocks_remain < 0)
                        clocks_remain = 3;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address();
                        regs[Reg::A] = regs[Reg::A] & read_memory(address);
                        regs[Reg::PC] += 3
                        update_and_flags();
                    }
                    break;
                case 0x3D: // AND ABSOLUTE,X
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if(absolute/256 < (absolute+regs[Reg::X])/256) // Page boundary crossed
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::X];
                        regs[Reg::A]  = regs[Reg::A] & read_memory(address);
                        regs[Reg::PC] += 3;
                        update_and_flags();
                    }
                    break;
                case 0x39: // AND ABSOLUTE,Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_absolute_address();
                        if(absolute/256 < (absolute+regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 4;
                        else
                            clocks_remain = 3;
                    }
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_absolute_address() + regs[Reg::Y];
                        regs[Reg::A] = regs[Reg::A] & read_memory(address);
                        regs[Reg::PC] += 3;
                        update_and_flags();
                    }
                    break;
                case 0x21: // AND (INDIRECT,X)
                    if(clocks_remain < 0)
                        clocks_remain = 5;
                    else if(clocks_remain == 0)
                    {
                        unsigned short address = get_indirect_x_address();
                        regs[Reg::A] = regs[Reg::A] & read_memory(address);
                        regs[Reg::PC] += 2;
                        update_and_flags();
                    }
                    break;
                case 0x31: // AND (INDIRECT),Y
                    if(clocks_remain < 0)
                    {
                        unsigned short absolute = get_address_from_zp();
                        if(absolute/256 < (absolute+regs[Reg::Y])/256) // Page boundary crossed
                            clocks_remain = 5;
                        else
                            clocks_remain = 4;
                    }
                    else if(clocks_remain==0)
                    {
                        unsigned short address = get_address_from_zp() + regs[Reg::Y];
                        regs[Reg::A] = regs[Reg::A] & read_memory(address);
                        regs[Reg::PC] += 2;
                        update_and_flags();
                    }
                    break;
            }
            cycle++;
        }

        unsigned short get_indirect_x_address()
        {
            unsigned short zp_address = (read_memory(regs[Reg::PC] + 1) + regs[Reg::X]) % 255; // Address stored in zero page to be read from
            return (read_memory(zp_address + 1) << 8) + (read_memory(zp_address));
        }

        unsigned short get_address_from_zp() // For (INDIRECT),Y addressing
        {
            unsigned short zp_address = read_memory(regs[Reg::PC] + 1);
            return (read_memory(zp_address + 1) << 8) + (read_memory(zp_address));
        }

        unsigned short get_absolute_address()
        {
            return (read_memory(regs[Reg::PC] + 2) << 8) + (read_memory(regs[Reg::PC] + 1));
        }

        unsigned char read_memory(int address)
        {
            if(address < 2048)
            {
                std::cout << "Reading memory from 0x" << std::hex << address << ": got 0x" << (int)int_memory[address] << std::dec << std::endl;
                return int_memory[address];
            }
            else
                return 0;
        }
};

int main()
{
    CPU cpu = CPU();
    cpu.regs[CPU::Reg::A] = 0x1;
    cpu.regs[CPU::Reg::Y] = 0x4;
    cpu.int_memory[0] = 0x71;
    cpu.int_memory[1] = 0x1;
    cpu.int_memory[2] = 0x01;
    cpu.int_memory[0x105] = 0xBD;
    while(cpu.cycle < 10)
    {
        cpu.do_cycle();
    }
}
<|endoftext|>


<commit_before>/// Implementation of the Number-Theoretical Transform in GF(P) Galois field
#include <iostream>
#include <algorithm>
#include <stdint.h>

#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#define MY_CPU_AMD64
#endif

#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#endif

typedef uint32_t ElementT;        // data items type, 32-bit unsigned integer for GF(P) computations with P>65536
typedef uint64_t DoubleElementT;  // twice wider type to hold intermediate results

// Reverse-binary reindexing
template <typename T>
void scramble (T* data, size_t nn)
{
    size_t n, mmax, m, j, istep, i;

    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            std::swap(data[j-1], data[i-1]);
            std::swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };
}

template <ElementT P>
ElementT GF_Add (ElementT X, ElementT Y)
{
    ElementT res = X + Y;
    return (res>=P || res<X)? res-P : res;
}

template <ElementT P>
ElementT GF_Sub (ElementT X, ElementT Y)
{
    ElementT res = X - Y;
    return res<=X? res : res+P;
}

// GF_Mul64 is optimized for 64-bit CPUs
template <ElementT P>
ElementT GF_Mul64 (ElementT X, ElementT Y)
{
    return ElementT( (DoubleElementT(X)*Y) % P);
}

// GF_Mul32 is optimized for 32-bit CPUs, SIMD and GPUs
template <ElementT P>
ElementT GF_Mul32 (ElementT X, ElementT Y)
{
    // invP32 := (2**64)/P - 2**32  :  if 2**31<P<2**32, then 2**32 < (2**64)/P < 2**33, and invP32 is a 32-bit value
    const DoubleElementT estInvP = ((DoubleElementT(1)<<63) / P) << 1;                          // == invP & (~1)
    const ElementT       invP32  = ElementT(estInvP*P > (estInvP+1)*P? estInvP : estInvP+1);    // we can't use 1<<64 for exact invP computation so, when required, we add one in other way
    DoubleElementT res = DoubleElementT(X)*Y;
    res  -=  ((res + (res>>32)*invP32) >> 32) * P;    // The same as res -= ((res*invP) >> 64) * P, where invP = (2**64)/P, but optimized for 32-bit computations
    return ElementT(res>=P? ElementT(res)-P : res);
}

#ifdef MY_CPU_64BIT
#define GF_Mul GF_Mul64
#else
#define GF_Mul GF_Mul32
#endif

template <size_t N, size_t SIZE, typename T, T P>
class DanielsonLanczos
{
    DanielsonLanczos<N/2,SIZE,T,P> next;
public:
    void apply (T* data, T root)
    {
        T root_sqr = GF_Mul<P> (root, root);  // first root of power N of 1
        if (N>1024) {
            #pragma omp task
            next.apply (data,   root_sqr);
            #pragma omp task
            next.apply (data+N, root_sqr);
            #pragma omp taskwait
        } else {
            next.apply (data,   root_sqr);
            next.apply (data+N, root_sqr);
        }

        T root_i = root;   // first root of power 2N of 1
        for (size_t i=0; i<N*SIZE; i+=SIZE) {
            for (size_t k=0; k<SIZE; k++) {
                size_t i1 = i+k, i2 = i+k+N*SIZE;
                T temp   = GF_Mul<P> (root_i, data[i2]);
                data[i2] = GF_Sub<P> (data[i1], temp);
                data[i1] = GF_Add<P> (data[i1], temp);
            }
            root_i = GF_Mul<P> (root_i, root);  // next root of power 2N of 1
        }
    }
};

template<size_t SIZE, typename T, T P>
class DanielsonLanczos<0,SIZE,T,P> {
public:
   void apply(T* data, T root) { }
};

template <size_t Exp, size_t SIZE, typename T, T P>
class NTT
{
    enum { N = 1<<Exp };
    DanielsonLanczos<N,SIZE,T,P> recursion;
public:
    void ntt (T* data)
    {
        T root = 1557;                      // init 'root' with root of 1 of power 2**20 in GF(0xFFF00001)
        for (int i=20; --i>Exp; )
            root = GF_Mul<P> (root, root);  // find root of 1 of power 2N
        scramble(data,N);
        recursion.apply(data,root);
    }
};

// Find first root of 1 of power 2**N
template <typename T, T P>
void FindRoot (int N)
{
    for (T i=2; i<P; i++)
    {
        T q = i;
        for (int j=0; j<N; j++)
        {
            if (q==1)  goto next;
            q = GF_Mul<P> (q,q);
        }
        if (q==1)
        {
            std::cout << i << "\n";
            break;
        }
next:;
    }
}

// Test the GF_Mul32 correctness
template <ElementT P>
void Test_GF_Mul32()
{
    int n = 0;
    for (ElementT i=P; --i; )
    {
        std::cout << std::hex << "\r" << i << "...";
        for (ElementT j=i; --j; )
            if (GF_Mul64<P> (i,j)  !=  GF_Mul32<P> (i,j))
            {
                std::cout << std::hex << "\r" << i << "*" << j << "=" << GF_Mul64<P> (i,j) << " != " << GF_Mul32<P> (i,j) << "\n" ;
                if (++n>10) return;
            }
    }
}

int main()
{
    const ElementT P = 0xFFF00001;
    // Test_GF_Mul32<P>();
    // FindRoot<ElementT,P>(20);  // prints 1557

    const size_t SIZE = 128<<20;  // 512 MB
    ElementT *data = new ElementT[SIZE];
    for (int i=0; i<SIZE; i++)
        data[i] = i;
    NTT<19,SIZE/1048576,ElementT,P> transformer;
    #pragma omp parallel num_threads(16)
    #pragma omp single
    transformer.ntt(data);
    return 0;
}
<commit_msg>NTT: replaced recursive NTT function template with recursive call<commit_after>/// Implementation of the Number-Theoretical Transform in GF(P) Galois field
#include <iostream>
#include <algorithm>
#include <stdint.h>

#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#define MY_CPU_AMD64
#endif

#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#endif

typedef uint32_t ElementT;        // data items type, 32-bit unsigned integer for GF(P) computations with P>65536
typedef uint64_t DoubleElementT;  // twice wider type to hold intermediate results

// Reverse-binary reindexing
template <typename T>
void scramble (T* data, size_t nn)
{
    size_t n, mmax, m, j, istep, i;

    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            std::swap(data[j-1], data[i-1]);
            std::swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };
}

template <ElementT P>
ElementT GF_Add (ElementT X, ElementT Y)
{
    ElementT res = X + Y;
    return (res>=P || res<X)? res-P : res;
}

template <ElementT P>
ElementT GF_Sub (ElementT X, ElementT Y)
{
    ElementT res = X - Y;
    return res<=X? res : res+P;
}

// GF_Mul64 is optimized for 64-bit CPUs
template <ElementT P>
ElementT GF_Mul64 (ElementT X, ElementT Y)
{
    return ElementT( (DoubleElementT(X)*Y) % P);
}

// GF_Mul32 is optimized for 32-bit CPUs, SIMD and GPUs
template <ElementT P>
ElementT GF_Mul32 (ElementT X, ElementT Y)
{
    // invP32 := (2**64)/P - 2**32  :  if 2**31<P<2**32, then 2**32 < (2**64)/P < 2**33, and invP32 is a 32-bit value
    const DoubleElementT estInvP = ((DoubleElementT(1)<<63) / P) << 1;                          // == invP & (~1)
    const ElementT       invP32  = ElementT(estInvP*P > (estInvP+1)*P? estInvP : estInvP+1);    // we can't use 1<<64 for exact invP computation so, when required, we add one in other way
    DoubleElementT res = DoubleElementT(X)*Y;
    res  -=  ((res + (res>>32)*invP32) >> 32) * P;    // The same as res -= ((res*invP) >> 64) * P, where invP = (2**64)/P, but optimized for 32-bit computations
    return ElementT(res>=P? ElementT(res)-P : res);
}

#ifdef MY_CPU_64BIT
#define GF_Mul GF_Mul64
#else
#define GF_Mul GF_Mul32
#endif

template <typename T, T P>
void apply (T* data, size_t N, size_t SIZE, T root)
{
    T root_sqr = GF_Mul<P> (root, root);  // first root of power N of 1
    if (N>1024) {
        #pragma omp task
        apply<T,P> (data,   N/2, SIZE, root_sqr);
        #pragma omp task
        apply<T,P> (data+N, N/2, SIZE, root_sqr);
        #pragma omp taskwait
    } else if (N>1) {
        apply<T,P> (data,   N/2, SIZE, root_sqr);
        apply<T,P> (data+N, N/2, SIZE, root_sqr);
    }

    T root_i = root;   // first root of power 2N of 1
    for (size_t i=0; i<N*SIZE; i+=SIZE) {
        for (size_t k=0; k<SIZE; k++) {
            size_t i1 = i+k, i2 = i+k+N*SIZE;
            T temp   = GF_Mul<P> (root_i, data[i2]);
            data[i2] = GF_Sub<P> (data[i1], temp);
            data[i1] = GF_Add<P> (data[i1], temp);
        }
        root_i = GF_Mul<P> (root_i, root);  // next root of power 2N of 1
    }
}

template <size_t Exp, size_t SIZE, typename T, T P>
class NTT
{
    enum { N = 1<<Exp };
public:
    void ntt (T* data)
    {
        T root = 1557;                      // init 'root' with root of 1 of power 2**20 in GF(0xFFF00001)
        for (int i=20; --i>Exp; )
            root = GF_Mul<P> (root, root);  // find root of 1 of power 2N
        scramble(data,N);
        apply<T,P> (data, N, SIZE, root);
    }
};

// Find first root of 1 of power 2**N
template <typename T, T P>
void FindRoot (int N)
{
    for (T i=2; i<P; i++)
    {
        T q = i;
        for (int j=0; j<N; j++)
        {
            if (q==1)  goto next;
            q = GF_Mul<P> (q,q);
        }
        if (q==1)
        {
            std::cout << i << "\n";
            break;
        }
next:;
    }
}

// Test the GF_Mul32 correctness
template <ElementT P>
void Test_GF_Mul32()
{
    int n = 0;
    for (ElementT i=P; --i; )
    {
        std::cout << std::hex << "\r" << i << "...";
        for (ElementT j=i; --j; )
            if (GF_Mul64<P> (i,j)  !=  GF_Mul32<P> (i,j))
            {
                std::cout << std::hex << "\r" << i << "*" << j << "=" << GF_Mul64<P> (i,j) << " != " << GF_Mul32<P> (i,j) << "\n" ;
                if (++n>10) return;
            }
    }
}

int main()
{
    const ElementT P = 0xFFF00001;
    // Test_GF_Mul32<P>();
    // FindRoot<ElementT,P>(20);  // prints 1557

    const size_t SIZE = 128<<20;  // 512 MB
    ElementT *data = new ElementT[SIZE];
    for (int i=0; i<SIZE; i++)
        data[i] = i;
    NTT<19,SIZE/1048576,ElementT,P> transformer;
    #pragma omp parallel num_threads(16)
    #pragma omp single
    transformer.ntt(data);
    return 0;
}
<|endoftext|>


<commit_before>#ifndef Rice__detail__ruby__hpp_
#define Rice__detail__ruby__hpp_

/*! \file
 * \brief Hacks for addressing incompatibilities between various Ruby
 * versions.
 */

#include <cmath>

// missing.h that comes with the one-click installer doesn't properly
// check for double-definition of isinf
#ifdef isinf
#define HAVE_ISINF
#endif

#include "ruby_version_code.hpp"

// workaround for ruby 1.8.4, which defines eaccess and shouldn't
#if RICE__RUBY_VERSION_CODE <= 184
#define eaccess ruby_eaccess
#endif

#include <ruby.h>

#if RICE__RUBY_VERSION_CODE <= 184
#undef eaccess
#endif

#ifdef WIN32
#include "win32.hpp"
#endif

// This causes problems with certain C++ libraries
#undef TYPE

//! A function that takes a VALUE as a parameter and returns a VALUE.
// TODO: Casting from a C++ function to an extern "C" function won't
// work on all platforms.  I'm not sure what to do about this.
extern "C" typedef VALUE (*RUBY_VALUE_FUNC)(VALUE);

// Fix Ruby RUBY_METHOD_FUNC from macro to typedef
#if defined(RUBY_METHOD_FUNC)
# undef RUBY_METHOD_FUNC
  extern "C" typedef VALUE (*RUBY_METHOD_FUNC)(ANYARGS);
#endif

#ifndef RSTRING_LEN
#define RSTRING_LEN(str) RSTRING(str)->len
#endif

#ifndef RSTRING_PTR
#define RSTRING_PTR(str) RSTRING(str)->ptr
#endif

#ifndef RARRAY_LEN
#define RARRAY_LEN(arr) RARRAY(arr)->len
#endif

#ifndef RARRAY_PTR
#define RARRAY_PTR(arr) RARRAY(arr)->ptr
#endif

#ifndef RHASH_TBL
#define RHASH_TBL(hsh) RHASH(hsh)->tbl
#endif

// ruby.h has a few defines that conflict with Visual Studio's STL
#if defined(_MSC_VER)
  #undef write
  #undef read
  #undef bind
#endif

#if RICE__RUBY_VERSION_CODE < 190
namespace Rice
{
  namespace detail
  {
    inline VALUE rb_errinfo() { return ruby_errinfo; }
    inline void rb_set_errinfo(VALUE exc) { ruby_errinfo = exc; }
  } // detail
} // Rice
#define rb_errinfo() ::Rice::detail::rb_errinfo()
#define rb_set_errinfo(exc) ::Rice::detail::rb_set_errinfo(exc)
#endif

#endif // Rice__detail__ruby__hpp_

<commit_msg>Define RCLASS_M_TBL on versions of ruby that don't define it.<commit_after>#ifndef Rice__detail__ruby__hpp_
#define Rice__detail__ruby__hpp_

/*! \file
 * \brief Hacks for addressing incompatibilities between various Ruby
 * versions.
 */

#include <cmath>

// missing.h that comes with the one-click installer doesn't properly
// check for double-definition of isinf
#ifdef isinf
#define HAVE_ISINF
#endif

#include "ruby_version_code.hpp"

// workaround for ruby 1.8.4, which defines eaccess and shouldn't
#if RICE__RUBY_VERSION_CODE <= 184
#define eaccess ruby_eaccess
#endif

#include <ruby.h>

#if RICE__RUBY_VERSION_CODE <= 184
#undef eaccess
#endif

#ifdef WIN32
#include "win32.hpp"
#endif

// This causes problems with certain C++ libraries
#undef TYPE

//! A function that takes a VALUE as a parameter and returns a VALUE.
// TODO: Casting from a C++ function to an extern "C" function won't
// work on all platforms.  I'm not sure what to do about this.
extern "C" typedef VALUE (*RUBY_VALUE_FUNC)(VALUE);

// Fix Ruby RUBY_METHOD_FUNC from macro to typedef
#if defined(RUBY_METHOD_FUNC)
# undef RUBY_METHOD_FUNC
  extern "C" typedef VALUE (*RUBY_METHOD_FUNC)(ANYARGS);
#endif

#ifndef RSTRING_LEN
#define RSTRING_LEN(str) RSTRING(str)->len
#endif

#ifndef RSTRING_PTR
#define RSTRING_PTR(str) RSTRING(str)->ptr
#endif

#ifndef RARRAY_LEN
#define RARRAY_LEN(arr) RARRAY(arr)->len
#endif

#ifndef RARRAY_PTR
#define RARRAY_PTR(arr) RARRAY(arr)->ptr
#endif

#ifndef RHASH_TBL
#define RHASH_TBL(hsh) RHASH(hsh)->tbl
#endif

#ifndef RCLASS_M_TBL
#define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
#endif

// ruby.h has a few defines that conflict with Visual Studio's STL
#if defined(_MSC_VER)
  #undef write
  #undef read
  #undef bind
#endif

#if RICE__RUBY_VERSION_CODE < 190
namespace Rice
{
  namespace detail
  {
    inline VALUE rb_errinfo() { return ruby_errinfo; }
    inline void rb_set_errinfo(VALUE exc) { ruby_errinfo = exc; }
  } // detail
} // Rice
#define rb_errinfo() ::Rice::detail::rb_errinfo()
#define rb_set_errinfo(exc) ::Rice::detail::rb_set_errinfo(exc)
#endif

#endif // Rice__detail__ruby__hpp_

<|endoftext|>