<commit_before>#include "game.h"
#include "git_versioning.h"

#include <iostream>
using std::cout;
using std::endl;

// in binding.cpp
void register_all_classes( lua_State* L );

void Game::initialiseAllegro()
{
    al_init();
    al_install_mouse();
    al_install_keyboard();
    al_init_image_addon();
    al_init_font_addon();
    al_init_ttf_addon();
}

bool Game::createDisplay()
{
    al_set_new_display_flags( ALLEGRO_RESIZABLE );
    display = al_create_display( SCREEN_W, SCREEN_H );
    if( display == nullptr )
        return false;
    al_set_window_title( display, "My Game" );

    resize();

    return true;
}

void Game::resize()
{
    width = al_get_display_width( display );
    height = al_get_display_height( display );

    scaleX = width / (float)SCREEN_W;
    scaleY = height / (float)SCREEN_H;

    cout << "X scale: " << scaleX << endl;
    cout << "Y scale: " << scaleY << endl;
    cout << endl;

    ALLEGRO_TRANSFORM trans;
    al_identity_transform(&trans);
    al_scale_transform(&trans, scaleX, scaleY);
    al_use_transform(&trans);
}

void Game::registerEventSources()
{
    frameTimer = al_create_timer( 1.0 / 60.0 );  // 60 FPS
    scriptTimer = al_create_timer( 1.0 / 100.0 ); // Update script called 100x per second
    eventQueue = al_create_event_queue();

    al_register_event_source( eventQueue, al_get_keyboard_event_source() );
    al_register_event_source( eventQueue, al_get_mouse_event_source() );
    al_register_event_source( eventQueue, al_get_display_event_source(display) );
    al_register_event_source( eventQueue, al_get_timer_event_source(frameTimer) );
    al_register_event_source( eventQueue, al_get_timer_event_source(scriptTimer) );

    al_start_timer( frameTimer );
    al_start_timer( scriptTimer );
}

void Game::initialiseLua()
{
    L = luaL_newstate();
    luaL_openlibs( L );

    register_all_classes( L );

    lua_pushlightuserdata( L, this );
    lua_setfield( L, LUA_REGISTRYINDEX, LUA_GAME_INDEX );

    lua_register( L, "quit", Game::quit );

    FontBinding::push( L, font );
    lua_setglobal( L, "fixed_font" );

    RenderListBinding::push( L, renderlist );
    lua_setglobal( L, "renderlist" );

    LuaRef info = LuaRef::newTable( L );
    info["width"] = SCREEN_W;
    info["height"] = SCREEN_H;
    info["gitver"] = GIT_REPO_VERSION_STR;
    info.push();
    lua_setglobal( L, "info" );
}

bool Game::boot()
{
    renderlist = std::make_shared<RenderList>();

    initialiseAllegro();

    if( ! createDisplay() )
        return false;

    registerEventSources();

    font = std::make_shared<Font>( "data/fixed_font.tga", 0, 0 );

    icon = al_load_bitmap( "data/icon.tga" );

    if( !font || !icon )
        return false;

    al_set_display_icon( display, icon );

    initialiseLua();

    FontPtr console_font = std::make_shared<Font>( "data/liberation_mono/LiberationMono-Bold.ttf", -16, ALLEGRO_TTF_NO_KERNING );

    console = std::make_shared<Console>( L, console_font, SCREEN_W );
    console->setOrder(255);
    console->print( std::string(  "Está es una prueba\nTeşekker edirim\nOne\t1\nTwo\t2\nÜç\t3\nDört\t4" ) );

    redraw = true;

    return true;
}

void Game::setScene()
{
    using std::make_shared;

    RenderListPtr rl = make_shared<RenderList>();

    rl->add( make_shared<Rectangle>( 4, 4,  100, 30, 8, 8, al_map_rgba(58,68,115,200)));
    rl->add( make_shared<Rectangle>( 4, 34, 100, 60, 8, 8, al_map_rgba(58,68,15,200)));
    rl->add( make_shared<Rectangle>( 4, 64, 120, 90, 8, 8, al_map_rgba(58,28,75,200)));

    fpsText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 54, 8 );
    rl->add( fpsText );

    spsText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 54, 38 );
    rl->add( spsText );

    mouseText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 61, 68 );
    rl->add( mouseText );

    rl->setOrder( 254 );

    renderlist->insert( std::move(rl) );

    updateMouseText();
}

void Game::updateMouseText()
{
    char mouseStr[MAX_BUTTONS+1];

    for( int i=1; i < MAX_BUTTONS; i++ )
        mouseStr[i-1] = mouse.buttons[i] ? '^' : '_';

    mouseStr[MAX_BUTTONS-1] = 0;

    mouseText->clearText();
    mouseText << "Mouse: [" << mouseStr << "]";
}

void Game::run()
{
    if( luaL_dofile( L, "scripts/main.lua" ) )
    {
        std::cerr << lua_tostring( L, -1 ) << std::endl;
        return;
    }

    LuaRef luaUpdate( L, "update" );
    LuaRef luaKeyEvent( L, "keyEvent" );
    LuaRef luaMouseEvent( L, "mouseEvent" );

    // Check scripts are sane.
    if( ! luaUpdate.isFunction() )
    {
        std::cerr << "Lua update function is not defined." << std::endl;
        shouldStop = true;
    }
    if( ! luaKeyEvent.isFunction() )
    {
        std::cerr << "Lua keyEvent function is not defined." << std::endl;
        shouldStop = true;
    }
    if( ! luaMouseEvent.isFunction() )
    {
        std::cerr << "Lua mouseEvent function is not defined." << std::endl;
        shouldStop = true;
    }

    int fps_accum = 0, fps = 0;
    double fps_time = 0;

    int sps_accum = 0, sps = 0;
    double sps_time = 0;

    while( ! shouldStop )
    {
        ALLEGRO_EVENT event;
        al_wait_for_event( eventQueue, &event );

        if( event.type == ALLEGRO_EVENT_DISPLAY_CLOSE )
            break;

        try {
            if( event.type == ALLEGRO_EVENT_KEY_CHAR )
            {
                if( event.keyboard.keycode == ALLEGRO_KEY_ESCAPE )
                {
                    if( console->isVisible() )
                    {
                        console->toggleVisibility();
                        continue;
                    }
                    else
                    {
                        // We grab it here, as 'quit' may change depending
                        // on what is happening.
                        LuaRef quit( L, "quit" );
                        if( quit.isFunction() ) {
                            quit();
                        }
                        continue;
                    }
                }

                if( console->isVisible() )
                {
                    if( console->injectKeyPress( event ) )
                    {
                        redraw = true;
                        continue;
                    }
                }
                else
                {
                    if( event.keyboard.keycode == ALLEGRO_KEY_TILDE )
                    {
                        console->toggleVisibility();
                        continue;
                    }
                }

                luaKeyEvent( al_get_time(), event.keyboard.keycode, event.keyboard.unichar );
            }

            if( event.type == ALLEGRO_EVENT_TIMER && event.timer.source == frameTimer )
            {
                double t = al_get_time();
                fps_accum++;

                if( t - fps_time >= 1 )
                {
                    fps = fps_accum;
                    fps_accum = 0;
                    fps_time = t;
                    fpsText->clearText();
                    fpsText << "FPS:  " << fps;
                }

                redraw = true;
            }

            if( event.type == ALLEGRO_EVENT_TIMER && event.timer.source == scriptTimer )
            {
                double t = al_get_time();
                sps_accum++;
                if( t - sps_time >= 1 )
                {
                    sps = sps_accum;
                    sps_accum = 0;
                    sps_time = t;
                    spsText->clearText();
                    spsText << "SPS: " << sps;
                }

                luaUpdate( t );
                console->resume();
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ) {
                if( event.mouse.button < MAX_BUTTONS )
                    mouse.buttons[event.mouse.button] = true;
                updateMouseText();
                luaMouseEvent( al_get_time(), "down", event.mouse.button );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP ) {
                if( event.mouse.button < MAX_BUTTONS )
                    mouse.buttons[event.mouse.button] = false;
                updateMouseText();
                luaMouseEvent( al_get_time(), "up", event.mouse.button );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_AXES || event.type == ALLEGRO_EVENT_MOUSE_WARPED ) {
                luaMouseEvent( al_get_time(), "move", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z,
                        event.mouse.dx / scaleX,
                        event.mouse.dy / scaleY,
                        event.mouse.dz
                        );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY ) {
                luaMouseEvent( al_get_time(), "enter", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z
                        );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY ) {
                luaMouseEvent( al_get_time(), "leave", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z
                        );
            }
        }
        catch( LuaException &e )
        {
            std::cerr << e.what() << std::endl;
        }

        if( event.type == ALLEGRO_EVENT_DISPLAY_RESIZE )
        {
            al_acknowledge_resize( display );

            resize();

            redraw = true;
        }

        if( redraw && al_is_event_queue_empty( eventQueue ) )
        {
            redraw = false;

            al_clear_to_color( al_map_rgb( 83, 24, 24 ) );

            renderlist->render();

            console->render();

            al_flip_display();
        }
    }
}

void Game::deregisterEventSources()
{
    if( eventQueue )
    {
        al_destroy_event_queue( eventQueue );
        eventQueue = nullptr;
    }
}

void Game::destroyDisplay()
{
    if( display )
    {
        al_destroy_display( display );
        display = nullptr;
    }
}

Game::~Game()
{
    console.reset();
    if( L ) {
        lua_close( L );
    }
    deregisterEventSources();
    destroyDisplay();
}

int Game::quit( lua_State *L )
{
    lua_getfield( L, LUA_REGISTRYINDEX, LUA_GAME_INDEX );
    Game* self = static_cast<Game*>(lua_touserdata( L, -1 ));

    self->shouldStop = true;

    return 0;
}
<commit_msg>Show git versioning in console at start.<commit_after>#include "game.h"
#include "git_versioning.h"

#include <iostream>
using std::cout;
using std::endl;

// in binding.cpp
void register_all_classes( lua_State* L );

void Game::initialiseAllegro()
{
    al_init();
    al_install_mouse();
    al_install_keyboard();
    al_init_image_addon();
    al_init_font_addon();
    al_init_ttf_addon();
}

bool Game::createDisplay()
{
    al_set_new_display_flags( ALLEGRO_RESIZABLE );
    display = al_create_display( SCREEN_W, SCREEN_H );
    if( display == nullptr )
        return false;
    al_set_window_title( display, "My Game" );

    resize();

    return true;
}

void Game::resize()
{
    width = al_get_display_width( display );
    height = al_get_display_height( display );

    scaleX = width / (float)SCREEN_W;
    scaleY = height / (float)SCREEN_H;

    cout << "X scale: " << scaleX << endl;
    cout << "Y scale: " << scaleY << endl;
    cout << endl;

    ALLEGRO_TRANSFORM trans;
    al_identity_transform(&trans);
    al_scale_transform(&trans, scaleX, scaleY);
    al_use_transform(&trans);
}

void Game::registerEventSources()
{
    frameTimer = al_create_timer( 1.0 / 60.0 );  // 60 FPS
    scriptTimer = al_create_timer( 1.0 / 100.0 ); // Update script called 100x per second
    eventQueue = al_create_event_queue();

    al_register_event_source( eventQueue, al_get_keyboard_event_source() );
    al_register_event_source( eventQueue, al_get_mouse_event_source() );
    al_register_event_source( eventQueue, al_get_display_event_source(display) );
    al_register_event_source( eventQueue, al_get_timer_event_source(frameTimer) );
    al_register_event_source( eventQueue, al_get_timer_event_source(scriptTimer) );

    al_start_timer( frameTimer );
    al_start_timer( scriptTimer );
}

void Game::initialiseLua()
{
    L = luaL_newstate();
    luaL_openlibs( L );

    register_all_classes( L );

    lua_pushlightuserdata( L, this );
    lua_setfield( L, LUA_REGISTRYINDEX, LUA_GAME_INDEX );

    lua_register( L, "quit", Game::quit );

    FontBinding::push( L, font );
    lua_setglobal( L, "fixed_font" );

    RenderListBinding::push( L, renderlist );
    lua_setglobal( L, "renderlist" );

    LuaRef info = LuaRef::newTable( L );
    info["width"] = SCREEN_W;
    info["height"] = SCREEN_H;
    info["gitver"] = GIT_REPO_VERSION_STR;
    info.push();
    lua_setglobal( L, "info" );
}

bool Game::boot()
{
    renderlist = std::make_shared<RenderList>();

    initialiseAllegro();

    if( ! createDisplay() )
        return false;

    registerEventSources();

    font = std::make_shared<Font>( "data/fixed_font.tga", 0, 0 );

    icon = al_load_bitmap( "data/icon.tga" );

    if( !font || !icon )
        return false;

    al_set_display_icon( display, icon );

    initialiseLua();

    FontPtr console_font = std::make_shared<Font>( "data/liberation_mono/LiberationMono-Bold.ttf", -16, ALLEGRO_TTF_NO_KERNING );

    console = std::make_shared<Console>( L, console_font, SCREEN_W );
    console->setOrder(255);
    console->print( std::string( "Está es una prueba\nTeşekker edirim\nOne\t1\nTwo\t2\nÜç\t3\nDört\t4" ) );
    console->print( std::string( GIT_REPO_VERSION_STR ));

    redraw = true;

    return true;
}

void Game::setScene()
{
    using std::make_shared;

    RenderListPtr rl = make_shared<RenderList>();

    rl->add( make_shared<Rectangle>( 4, 4,  100, 30, 8, 8, al_map_rgba(58,68,115,200)));
    rl->add( make_shared<Rectangle>( 4, 34, 100, 60, 8, 8, al_map_rgba(58,68,15,200)));
    rl->add( make_shared<Rectangle>( 4, 64, 120, 90, 8, 8, al_map_rgba(58,28,75,200)));

    fpsText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 54, 8 );
    rl->add( fpsText );

    spsText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 54, 38 );
    rl->add( spsText );

    mouseText = make_shared<Text>( font, al_map_rgb( 255, 255, 255 ), 61, 68 );
    rl->add( mouseText );

    rl->setOrder( 254 );

    renderlist->insert( std::move(rl) );

    updateMouseText();
}

void Game::updateMouseText()
{
    char mouseStr[MAX_BUTTONS+1];

    for( int i=1; i < MAX_BUTTONS; i++ )
        mouseStr[i-1] = mouse.buttons[i] ? '^' : '_';

    mouseStr[MAX_BUTTONS-1] = 0;

    mouseText->clearText();
    mouseText << "Mouse: [" << mouseStr << "]";
}

void Game::run()
{
    if( luaL_dofile( L, "scripts/main.lua" ) )
    {
        std::cerr << lua_tostring( L, -1 ) << std::endl;
        return;
    }

    LuaRef luaUpdate( L, "update" );
    LuaRef luaKeyEvent( L, "keyEvent" );
    LuaRef luaMouseEvent( L, "mouseEvent" );

    // Check scripts are sane.
    if( ! luaUpdate.isFunction() )
    {
        std::cerr << "Lua update function is not defined." << std::endl;
        shouldStop = true;
    }
    if( ! luaKeyEvent.isFunction() )
    {
        std::cerr << "Lua keyEvent function is not defined." << std::endl;
        shouldStop = true;
    }
    if( ! luaMouseEvent.isFunction() )
    {
        std::cerr << "Lua mouseEvent function is not defined." << std::endl;
        shouldStop = true;
    }

    int fps_accum = 0, fps = 0;
    double fps_time = 0;

    int sps_accum = 0, sps = 0;
    double sps_time = 0;

    while( ! shouldStop )
    {
        ALLEGRO_EVENT event;
        al_wait_for_event( eventQueue, &event );

        if( event.type == ALLEGRO_EVENT_DISPLAY_CLOSE )
            break;

        try {
            if( event.type == ALLEGRO_EVENT_KEY_CHAR )
            {
                if( event.keyboard.keycode == ALLEGRO_KEY_ESCAPE )
                {
                    if( console->isVisible() )
                    {
                        console->toggleVisibility();
                        continue;
                    }
                    else
                    {
                        // We grab it here, as 'quit' may change depending
                        // on what is happening.
                        LuaRef quit( L, "quit" );
                        if( quit.isFunction() ) {
                            quit();
                        }
                        continue;
                    }
                }

                if( console->isVisible() )
                {
                    if( console->injectKeyPress( event ) )
                    {
                        redraw = true;
                        continue;
                    }
                }
                else
                {
                    if( event.keyboard.keycode == ALLEGRO_KEY_TILDE )
                    {
                        console->toggleVisibility();
                        continue;
                    }
                }

                luaKeyEvent( al_get_time(), event.keyboard.keycode, event.keyboard.unichar );
            }

            if( event.type == ALLEGRO_EVENT_TIMER && event.timer.source == frameTimer )
            {
                double t = al_get_time();
                fps_accum++;

                if( t - fps_time >= 1 )
                {
                    fps = fps_accum;
                    fps_accum = 0;
                    fps_time = t;
                    fpsText->clearText();
                    fpsText << "FPS:  " << fps;
                }

                redraw = true;
            }

            if( event.type == ALLEGRO_EVENT_TIMER && event.timer.source == scriptTimer )
            {
                double t = al_get_time();
                sps_accum++;
                if( t - sps_time >= 1 )
                {
                    sps = sps_accum;
                    sps_accum = 0;
                    sps_time = t;
                    spsText->clearText();
                    spsText << "SPS: " << sps;
                }

                luaUpdate( t );
                console->resume();
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ) {
                if( event.mouse.button < MAX_BUTTONS )
                    mouse.buttons[event.mouse.button] = true;
                updateMouseText();
                luaMouseEvent( al_get_time(), "down", event.mouse.button );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP ) {
                if( event.mouse.button < MAX_BUTTONS )
                    mouse.buttons[event.mouse.button] = false;
                updateMouseText();
                luaMouseEvent( al_get_time(), "up", event.mouse.button );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_AXES || event.type == ALLEGRO_EVENT_MOUSE_WARPED ) {
                luaMouseEvent( al_get_time(), "move", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z,
                        event.mouse.dx / scaleX,
                        event.mouse.dy / scaleY,
                        event.mouse.dz
                        );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY ) {
                luaMouseEvent( al_get_time(), "enter", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z
                        );
            }

            if( event.type == ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY ) {
                luaMouseEvent( al_get_time(), "leave", event.mouse.button,
                        event.mouse.x / scaleX,
                        event.mouse.y / scaleY,
                        event.mouse.z
                        );
            }
        }
        catch( LuaException &e )
        {
            std::cerr << e.what() << std::endl;
        }

        if( event.type == ALLEGRO_EVENT_DISPLAY_RESIZE )
        {
            al_acknowledge_resize( display );

            resize();

            redraw = true;
        }

        if( redraw && al_is_event_queue_empty( eventQueue ) )
        {
            redraw = false;

            al_clear_to_color( al_map_rgb( 83, 24, 24 ) );

            renderlist->render();

            console->render();

            al_flip_display();
        }
    }
}

void Game::deregisterEventSources()
{
    if( eventQueue )
    {
        al_destroy_event_queue( eventQueue );
        eventQueue = nullptr;
    }
}

void Game::destroyDisplay()
{
    if( display )
    {
        al_destroy_display( display );
        display = nullptr;
    }
}

Game::~Game()
{
    console.reset();
    if( L ) {
        lua_close( L );
    }
    deregisterEventSources();
    destroyDisplay();
}

int Game::quit( lua_State *L )
{
    lua_getfield( L, LUA_REGISTRYINDEX, LUA_GAME_INDEX );
    Game* self = static_cast<Game*>(lua_touserdata( L, -1 ));

    self->shouldStop = true;

    return 0;
}
<|endoftext|>


<commit_before>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <SDL_opengl.h>
#include <SDL.h>

#include <algorithm>
#include <cmath>

#include "game.hxx"
#include "player.hxx"
#include "globals.hxx"
#include "music_player.hxx"

#define ACCEL -0.15f
#define MIN_CONV 0.5f
#define MAX_CONV 2.5f

using namespace std;

Game::Game()
: currentConvulsion(0), targetConvulsion(0),
  playerAmplitude(0),
  enemyFactory(*this),
  speed(-2.0f)
{
  player = new Player(&field, &distortion, getNearClippingPlane(),
                      &playerDeath, this);
  field.add(player);
}

Game::~Game() {}

void Game::update(float et) {
  float distortionDiff = targetConvulsion - currentConvulsion;
  distortionDiff *= pow(0.2f, et);
  currentConvulsion = targetConvulsion - distortionDiff;
  distortion.setConvulsionMult(currentConvulsion);

  if (player)
    player->setAmplitude(playerAmplitude);

  enemyFactory.update(et, -speed);
  tunnel.update(et);
  field.update(et);

  float oldNear = getNearClippingPlane();
  speed += ACCEL*et;
  float nearDelta = getNearClippingPlane() - oldNear;
  float shift = speed*et;
  if (player) {
    player->shotSpeed = -speed;

    float oldz = player->getZ();
    player->advance(shift, nearDelta);
    if (player)
      shift = player->getZ() - oldz + nearDelta;
  }

  field.translateZ(shift);
  tunnel.translateZ(shift);
  distortion.translateZ(shift, -speed);
}

void Game::configureGL() {
  glEnable(GL_FOG);
  glFogi(GL_FOG_MODE, GL_LINEAR);
  glFogf(GL_FOG_DENSITY, 0.25f);
  glFogf(GL_FOG_START, max(1.0f, getNearClippingPlane()));
  glFogf(GL_FOG_END, max(1.1f, 1.1f*getSpawnDistance()));

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(-1, 1, -vheight, vheight, getNearClippingPlane(), 128.0f);
  glScalef(2.0f, 2.0f, 1);
  glTranslatef(-0.5f, -vheight/2.0f, 0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void Game::draw() {
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  tunnel.draw(distortion);
  field.draw();
}

void Game::motion(float x,float) {
  if (player)
    player->move(x);
}

void Game::button(unsigned button) {
  if (player) {
    if (button == SDL_BUTTON_LEFT)
      player->jump();
  }
}

bool Game::running() const {
  return !!player;
}

void Game::playerDeath(void* that) {
  ((Game*)that)->player = NULL;
}

float Game::getNearClippingPlane() const {
  return -1.5f/speed;
}

float Game::getSpawnDistance() const {
  return min(8*-speed, Tunnel::gridLength*Tunnel::gsqlen/2);
}

float Game::getPlayerX() const {
  return player? player->getX() : 0.5f;
}

static void amplitudeCallback(void* thisVoid, float amp) {
  ((Game*)thisVoid)->amplitude(amp);
}

void Game::amplitude(float amp) {
  // XXX Minor threading issues here; we could see a partial floating-point
  // update. Oh well.
  targetConvulsion = amp*(MAX_CONV - MIN_CONV) + MIN_CONV;
  playerAmplitude = amp;
}

void Game::startMusic(const char*const* list, unsigned len) {
  mixer.play(new MusicPlayer(list, len, amplitudeCallback, this), 0x7FFF);
}
<commit_msg>Reduce accel back to something sane.<commit_after>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <SDL_opengl.h>
#include <SDL.h>

#include <algorithm>
#include <cmath>

#include "game.hxx"
#include "player.hxx"
#include "globals.hxx"
#include "music_player.hxx"

#define ACCEL -0.015f
#define MIN_CONV 0.5f
#define MAX_CONV 2.5f

using namespace std;

Game::Game()
: currentConvulsion(0), targetConvulsion(0),
  playerAmplitude(0),
  enemyFactory(*this),
  speed(-2.0f)
{
  player = new Player(&field, &distortion, getNearClippingPlane(),
                      &playerDeath, this);
  field.add(player);
}

Game::~Game() {}

void Game::update(float et) {
  float distortionDiff = targetConvulsion - currentConvulsion;
  distortionDiff *= pow(0.2f, et);
  currentConvulsion = targetConvulsion - distortionDiff;
  distortion.setConvulsionMult(currentConvulsion);

  if (player)
    player->setAmplitude(playerAmplitude);

  enemyFactory.update(et, -speed);
  tunnel.update(et);
  field.update(et);

  float oldNear = getNearClippingPlane();
  speed += ACCEL*et;
  float nearDelta = getNearClippingPlane() - oldNear;
  float shift = speed*et;
  if (player) {
    player->shotSpeed = -speed;

    float oldz = player->getZ();
    player->advance(shift, nearDelta);
    if (player)
      shift = player->getZ() - oldz + nearDelta;
  }

  field.translateZ(shift);
  tunnel.translateZ(shift);
  distortion.translateZ(shift, -speed);
}

void Game::configureGL() {
  glEnable(GL_FOG);
  glFogi(GL_FOG_MODE, GL_LINEAR);
  glFogf(GL_FOG_DENSITY, 0.25f);
  glFogf(GL_FOG_START, max(1.0f, getNearClippingPlane()));
  glFogf(GL_FOG_END, max(1.1f, 1.1f*getSpawnDistance()));

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(-1, 1, -vheight, vheight, getNearClippingPlane(), 128.0f);
  glScalef(2.0f, 2.0f, 1);
  glTranslatef(-0.5f, -vheight/2.0f, 0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void Game::draw() {
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  tunnel.draw(distortion);
  field.draw();
}

void Game::motion(float x,float) {
  if (player)
    player->move(x);
}

void Game::button(unsigned button) {
  if (player) {
    if (button == SDL_BUTTON_LEFT)
      player->jump();
  }
}

bool Game::running() const {
  return !!player;
}

void Game::playerDeath(void* that) {
  ((Game*)that)->player = NULL;
}

float Game::getNearClippingPlane() const {
  return -1.5f/speed;
}

float Game::getSpawnDistance() const {
  return min(8*-speed, Tunnel::gridLength*Tunnel::gsqlen/2);
}

float Game::getPlayerX() const {
  return player? player->getX() : 0.5f;
}

static void amplitudeCallback(void* thisVoid, float amp) {
  ((Game*)thisVoid)->amplitude(amp);
}

void Game::amplitude(float amp) {
  // XXX Minor threading issues here; we could see a partial floating-point
  // update. Oh well.
  targetConvulsion = amp*(MAX_CONV - MIN_CONV) + MIN_CONV;
  playerAmplitude = amp;
}

void Game::startMusic(const char*const* list, unsigned len) {
  mixer.play(new MusicPlayer(list, len, amplitudeCallback, this), 0x7FFF);
}
<|endoftext|>


<commit_before><commit_msg>main.cpp -> rshell.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>Missing check for exception.<commit_after><|endoftext|>


<commit_before><commit_msg>Adicionando consts<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc
 *
 *   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 "etracer.h"

int main(int argc, char* argv[]) {
    TraceLog::getInstance().start(
            TraceConfig(BufferMode::fixed, 1000)
    );

    TraceLog::getInstance().logEvent("Tracing",
                                     "Started",
                                     TraceEvent::Type::Instant,
                                     0, 123, 0);
    TraceLog::getInstance().logEvent("Tracing",
                                     "Started",
                                     TraceEvent::Type::Instant,
                                     0, 123, 0);
    TraceLog::getInstance().stop();

    auto buffer(TraceLog::getInstance().getBuffer());

    std::cout << *buffer->begin() << std::endl;
    for(const auto& event : *buffer) {
        std::cout << event << std::endl;
        break;
    }

    return 0;
}<commit_msg>Update playground<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc
 *
 *   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 "etracer.h"

int main(int argc, char* argv[]) {
    TraceLog::getInstance().start(
            TraceConfig(BufferMode::fixed, 1000)
    );

    TraceLog::getInstance().logEvent("Tracing",
                                     "Started",
                                     TraceEvent::Type::Instant,
                                     0, 123, 0);
    TraceLog::getInstance().logEvent("Tracing",
                                     "Started",
                                     TraceEvent::Type::Instant,
                                     0, 123, 0);
    while(TraceLog::getInstance().isEnabled()) {
        TraceLog::getInstance().logEvent("Hello", "World", TraceEvent::Type::SyncStart, 0);
    }

    auto buffer(TraceLog::getInstance().getBuffer());

    for(const auto& event : *buffer) {
        std::cout << event << std::endl;
    }

    return 0;
}<|endoftext|>


<commit_before>#include "ibwrt.h"

class ibwrtWorker : public Nan::AsyncWorker {
	private:
		int ud;
		char *data;
		int len;
		int err;
		int status;
		int bytesWritten;

	public:
		ibwrtWorker( Nan::Callback *callback, int ud, char *data, int len ) : AsyncWorker( callback ), ud( ud ), data( data ), len( len ) {}

		~ibwrtWorker() {
			free( data );
		}

		void Execute() {

			status = ibwrt( ud, (void *) data, len );
			err = iberr;
			bytesWritten = ibcnt;

		}

		void HandleOKCallback() {

			v8::Local<v8::Value> argv[] = {
				Nan::New<v8::Number>( err ),
				Nan::New<v8::Number>( status ),
				Nan::New<v8::Number>( bytesWritten )
			};

			callback->Call( 3, argv, async_resource );

		}
};

NAN_METHOD( ibwrt ) {
	v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();

	int ud = info[0]->Int32Value(context).FromJust();

	v8::Local<v8::String> tmp = info[1]->ToString(context).ToLocalChecked();
	int len = tmp->Length();
	char *data = (char *) malloc( tmp->Length() + 1 );
	tmp->WriteUtf8( v8::Isolate::GetCurrent(), data, len );

	Nan::Callback *callback = new Nan::Callback( info[2].As<v8::Function>() );

	Nan::AsyncQueueWorker( new ibwrtWorker( callback, ud, data, len ) );

}
<commit_msg>Preserved backward compatibility to Node 8 and earlier<commit_after>#include "ibwrt.h"

class ibwrtWorker : public Nan::AsyncWorker {
	private:
		int ud;
		char *data;
		int len;
		int err;
		int status;
		int bytesWritten;

	public:
		ibwrtWorker( Nan::Callback *callback, int ud, char *data, int len ) : AsyncWorker( callback ), ud( ud ), data( data ), len( len ) {}

		~ibwrtWorker() {
			free( data );
		}

		void Execute() {

			status = ibwrt( ud, (void *) data, len );
			err = iberr;
			bytesWritten = ibcnt;

		}

		void HandleOKCallback() {

			v8::Local<v8::Value> argv[] = {
				Nan::New<v8::Number>( err ),
				Nan::New<v8::Number>( status ),
				Nan::New<v8::Number>( bytesWritten )
			};

			callback->Call( 3, argv, async_resource );

		}
};

NAN_METHOD( ibwrt ) {
	v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();

	int ud = info[0]->Int32Value(context).FromJust();

	v8::Local<v8::String> dataLocal = info[1]->ToString(context).ToLocalChecked();
	Nan::Utf8String dataStr(dataLocal);
	int len = dataStr.length();
	char *data = strdup( *dataStr );

	Nan::Callback *callback = new Nan::Callback( info[2].As<v8::Function>() );

	Nan::AsyncQueueWorker( new ibwrtWorker( callback, ud, data, len ) );

}
<|endoftext|>


<commit_before>#include <stdexcept>
#include <map>
#include <utility>
#include <xorg/gtest/xorg-gtest.h>
#include <linux/input.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#define XK_LATIN1
#include <X11/keysymdef.h>
#include <X11/XF86keysym.h>
#include <X11/Xutil.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>

#include "input-driver-test.h"
#include "helpers.h"

class SynapticsDriverTest : public InputDriverTest {
public:
    virtual void SetUp() {

        dev = std::auto_ptr<xorg::testing::evemu::Device>(
                new xorg::testing::evemu::Device(
                    RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad.desc"
                    )
                );
        InputDriverTest::SetUp();
    }

    virtual void SetUpConfigAndLog(const std::string &param) {
        server.SetOption("-logfile", "/tmp/Xorg-synaptics-driver-SynPS2.log");
        server.SetOption("-config", "/tmp/synaptics-SynPS2.conf");

        config.AddDefaultScreenWithDriver();
        config.AddInputSection("synaptics", "--device--",
                               "Option \"Protocol\"            \"event\"\n"
                               "Option \"CorePointer\"         \"on\"\n"
                               "Option \"TapButton1\"          \"1\"\n"
                               "Option \"GrabEventDevice\"     \"0\"\n"
                               "Option \"FastTaps\"            \"1\"\n"
                               "Option \"VertTwoFingerScroll\" \"1\"\n"
                               "Option \"Device\"              \"" + dev->GetDeviceNode() + "\"\n");
        config.WriteConfig("/tmp/synaptics-SynPS2.conf");
    }

protected:
    std::auto_ptr<xorg::testing::evemu::Device> dev;
};

TEST_F(SynapticsDriverTest, DevicePresent)
{
    int major = 2;
    int minor = 0;
    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));

    int ndevices;
    XIDeviceInfo *info;

    info = XIQueryDevice(Display(), XIAllDevices, &ndevices);

    /* VCP, VCK, VC XTEST keyboard, VC XTEST pointer, default keyboard, --device-- */
    ASSERT_EQ(6, ndevices);
    bool found = false;
    while(ndevices--) {
        if (strcmp(info[ndevices].name, "--device--") == 0) {
            ASSERT_EQ(found, false) << "Duplicate device" << std::endl;
            found = true;
        }
    }
    ASSERT_EQ(found, true);
    XIFreeDeviceInfo(info);
}

void check_buttons_event(::Display *display,
                        xorg::testing::evemu::Device *dev,
                        const std::string& events_path,
                        int button,
                        int expect_nevents) {

    dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
    XSync(display, False);

    ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
    XEvent btn;
    int nevents = 0;
    while(XPending(display)) {
        XNextEvent(display, &btn);

        ASSERT_EQ(btn.xbutton.type, ButtonPress);
        ASSERT_EQ(btn.xbutton.button, button);

        XNextEvent(display, &btn);
        ASSERT_EQ(btn.xbutton.type, ButtonRelease);
        ASSERT_EQ(btn.xbutton.button, button);

        nevents++;
    }

    ASSERT_EQ(expect_nevents, nevents);
}

TEST_F(SynapticsDriverTest, ScrollWheel)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-up.events", 4, 17);
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-down.events", 5, 10);
}

TEST_F(SynapticsDriverTest, TapEvent)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap.events", 1, 1);
}

void check_drag_event(::Display *display,
                      xorg::testing::evemu::Device *dev,
                      const std::string& events_path,
                      int expect_npress,
                      int expect_nmotion,
                      int expect_nrelease) {

    dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
    XSync(display, False);

    ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
    XEvent ev;
    int nevents = 0;

    while (XCheckMaskEvent (display, ButtonPressMask, &ev))
        nevents++;
    ASSERT_EQ(expect_npress, nevents);
    ASSERT_EQ(ev.xbutton.button, 1);

    nevents = 0;
    while (XCheckMaskEvent (display, PointerMotionMask, &ev))
        nevents++;
    ASSERT_EQ(expect_nmotion, nevents);

    nevents = 0;
    while (XCheckMaskEvent (display, ButtonReleaseMask, &ev))
        nevents++;
    ASSERT_EQ(expect_nrelease, nevents);
    ASSERT_EQ(ev.xbutton.button, 1);

    while(XPending(display))
        XNextEvent(display, &ev);
}

TEST_F(SynapticsDriverTest, TapAndDragEvent)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    /* 1 press, 30 moves then 1 release is what we expect */
    check_drag_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap-and-move.events", 1, 30, 1);
}

/* Bug 53037 - Device coordinate scaling breaks XWarpPointer requests

   If a device with a device coordinate range is the lastSlave, a
   WarpPointer request on some coordinates may end up on different pixels
   than requested. The server scales from screen to device coordinates, then
   back to screen - a rounding error may then change to the wrong pixel.

   https://bugs.freedesktop.org/show_bug.cgi?id=53037
 */
class SynapticsWarpTest : public SynapticsDriverTest,
                          public ::testing::WithParamInterface<std::pair<int, int> >{
};

TEST_P(SynapticsWarpTest, WarpScaling)
{
    SCOPED_TRACE("https://bugs.freedesktop.org/show_bug.cgi?id=53037");

    /* Play one event so this device is lastSlave */
    dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");

    int x = GetParam().first,
        y = GetParam().second;

    XWarpPointer(Display(), 0, DefaultRootWindow(Display()), 0, 0, 0, 0, x, y);

    Window root, child;
    int rx, ry, wx, wy;
    unsigned int mask;

    XQueryPointer(Display(), DefaultRootWindow(Display()), &root, &child,
                  &rx, &ry, &wx, &wy, &mask);
    ASSERT_EQ(root, DefaultRootWindow(Display()));
    /* Warping to negative should clip to 0 */
    ASSERT_EQ(rx, std::max(x, 0));
    ASSERT_EQ(ry, std::max(y, 0));
}

INSTANTIATE_TEST_CASE_P(, SynapticsWarpTest,
                        ::testing::Values(std::make_pair(0, 0),
                                          std::make_pair(1, 1),
                                          std::make_pair(2, 2),
                                          std::make_pair(200, 200),
                                          std::make_pair(-1, -1)
                            ));

class SynapticsDriverClickpadTest : public InputDriverTest {
public:
    virtual void SetUp() {
        dev = std::auto_ptr<xorg::testing::evemu::Device>(
                new xorg::testing::evemu::Device(
                    RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.desc"
                    )
                );
        InputDriverTest::SetUp();
    }

    virtual void SetUpConfigAndLog(const std::string &param) {
        server.SetOption("-logfile", "/tmp/Xorg-synaptics-driver-clickpad.log");
        server.SetOption("-config", "/tmp/synaptics-clickpad.conf");

        config.AddDefaultScreenWithDriver();
        config.AddInputSection("synaptics", "--device--",
                               "Option \"CorePointer\"         \"on\"\n"
                               "Option \"GrabEventDevice\"     \"0\"\n"
                               "Option \"Device\"              \"" + dev->GetDeviceNode() + "\"\n");
        config.WriteConfig("/tmp/synaptics-clickpad.conf");
    }

protected:
    std::auto_ptr<xorg::testing::evemu::Device> dev;
};

TEST_F(SynapticsDriverClickpadTest, ClickpadProperties)
{
    int major = 2;
    int minor = 0;
    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));

    int deviceid;
    ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);

    Atom clickpad_prop = XInternAtom(Display(), "Synaptics ClickPad", True);
    ASSERT_NE(clickpad_prop, None);

    Status status;
    Atom type;
    int format;
    unsigned long nitems, bytes_after;
    unsigned char *data;

    status = XIGetProperty(Display(), deviceid, clickpad_prop, 0, 1, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 8);
    ASSERT_EQ(nitems, 1);
    ASSERT_EQ(bytes_after, 0);
    ASSERT_EQ(data[0], 1);
    free(data);

    /* This option is assigned by the xorg.conf.d, it won't activate for
       xorg.conf devices. */
    Atom softbutton_props = XInternAtom(Display(), "Synaptics Soft Button Areas", True);
    ASSERT_NE(softbutton_props, None);

    status = XIGetProperty(Display(), deviceid, softbutton_props, 0, 8, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 32);
    ASSERT_EQ(nitems, 8);
    ASSERT_EQ(bytes_after, 0);

    int32_t *buttons = reinterpret_cast<int32_t*>(data);
    ASSERT_EQ(buttons[0], 0);
    ASSERT_EQ(buttons[1], 0);
    ASSERT_EQ(buttons[2], 0);
    ASSERT_EQ(buttons[3], 0);
    ASSERT_EQ(buttons[4], 0);
    ASSERT_EQ(buttons[5], 0);
    ASSERT_EQ(buttons[6], 0);
    ASSERT_EQ(buttons[7], 0);

    free(data);

}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<commit_msg>synaptics: add another test for SoftButtonAreas option through xorg.conf.d<commit_after>#include <stdexcept>
#include <map>
#include <utility>
#include <xorg/gtest/xorg-gtest.h>
#include <linux/input.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#define XK_LATIN1
#include <X11/keysymdef.h>
#include <X11/XF86keysym.h>
#include <X11/Xutil.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>

#include "input-driver-test.h"
#include "helpers.h"

class SynapticsDriverTest : public InputDriverTest {
public:
    virtual void SetUp() {

        dev = std::auto_ptr<xorg::testing::evemu::Device>(
                new xorg::testing::evemu::Device(
                    RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad.desc"
                    )
                );
        InputDriverTest::SetUp();
    }

    virtual void SetUpConfigAndLog(const std::string &param) {
        server.SetOption("-logfile", "/tmp/Xorg-synaptics-driver-SynPS2.log");
        server.SetOption("-config", "/tmp/synaptics-SynPS2.conf");

        config.AddDefaultScreenWithDriver();
        config.AddInputSection("synaptics", "--device--",
                               "Option \"Protocol\"            \"event\"\n"
                               "Option \"CorePointer\"         \"on\"\n"
                               "Option \"TapButton1\"          \"1\"\n"
                               "Option \"GrabEventDevice\"     \"0\"\n"
                               "Option \"FastTaps\"            \"1\"\n"
                               "Option \"VertTwoFingerScroll\" \"1\"\n"
                               "Option \"Device\"              \"" + dev->GetDeviceNode() + "\"\n");
        config.WriteConfig("/tmp/synaptics-SynPS2.conf");
    }

protected:
    std::auto_ptr<xorg::testing::evemu::Device> dev;
};

TEST_F(SynapticsDriverTest, DevicePresent)
{
    int major = 2;
    int minor = 0;
    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));

    int ndevices;
    XIDeviceInfo *info;

    info = XIQueryDevice(Display(), XIAllDevices, &ndevices);

    /* VCP, VCK, VC XTEST keyboard, VC XTEST pointer, default keyboard, --device-- */
    ASSERT_EQ(6, ndevices);
    bool found = false;
    while(ndevices--) {
        if (strcmp(info[ndevices].name, "--device--") == 0) {
            ASSERT_EQ(found, false) << "Duplicate device" << std::endl;
            found = true;
        }
    }
    ASSERT_EQ(found, true);
    XIFreeDeviceInfo(info);
}

void check_buttons_event(::Display *display,
                        xorg::testing::evemu::Device *dev,
                        const std::string& events_path,
                        int button,
                        int expect_nevents) {

    dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
    XSync(display, False);

    ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
    XEvent btn;
    int nevents = 0;
    while(XPending(display)) {
        XNextEvent(display, &btn);

        ASSERT_EQ(btn.xbutton.type, ButtonPress);
        ASSERT_EQ(btn.xbutton.button, button);

        XNextEvent(display, &btn);
        ASSERT_EQ(btn.xbutton.type, ButtonRelease);
        ASSERT_EQ(btn.xbutton.button, button);

        nevents++;
    }

    ASSERT_EQ(expect_nevents, nevents);
}

TEST_F(SynapticsDriverTest, ScrollWheel)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-up.events", 4, 17);
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-down.events", 5, 10);
}

TEST_F(SynapticsDriverTest, TapEvent)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap.events", 1, 1);
}

void check_drag_event(::Display *display,
                      xorg::testing::evemu::Device *dev,
                      const std::string& events_path,
                      int expect_npress,
                      int expect_nmotion,
                      int expect_nrelease) {

    dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
    XSync(display, False);

    ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
    XEvent ev;
    int nevents = 0;

    while (XCheckMaskEvent (display, ButtonPressMask, &ev))
        nevents++;
    ASSERT_EQ(expect_npress, nevents);
    ASSERT_EQ(ev.xbutton.button, 1);

    nevents = 0;
    while (XCheckMaskEvent (display, PointerMotionMask, &ev))
        nevents++;
    ASSERT_EQ(expect_nmotion, nevents);

    nevents = 0;
    while (XCheckMaskEvent (display, ButtonReleaseMask, &ev))
        nevents++;
    ASSERT_EQ(expect_nrelease, nevents);
    ASSERT_EQ(ev.xbutton.button, 1);

    while(XPending(display))
        XNextEvent(display, &ev);
}

TEST_F(SynapticsDriverTest, TapAndDragEvent)
{
    XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
    /* the server takes a while to start up bust the devices may not respond
       to events yet. Add a noop call that just delays everything long
       enough for this test to work */
    XInternAtom(Display(), "foo", True);
    XFlush(Display());
    /* 1 press, 30 moves then 1 release is what we expect */
    check_drag_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap-and-move.events", 1, 30, 1);
}

/* Bug 53037 - Device coordinate scaling breaks XWarpPointer requests

   If a device with a device coordinate range is the lastSlave, a
   WarpPointer request on some coordinates may end up on different pixels
   than requested. The server scales from screen to device coordinates, then
   back to screen - a rounding error may then change to the wrong pixel.

   https://bugs.freedesktop.org/show_bug.cgi?id=53037
 */
class SynapticsWarpTest : public SynapticsDriverTest,
                          public ::testing::WithParamInterface<std::pair<int, int> >{
};

TEST_P(SynapticsWarpTest, WarpScaling)
{
    SCOPED_TRACE("https://bugs.freedesktop.org/show_bug.cgi?id=53037");

    /* Play one event so this device is lastSlave */
    dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");

    int x = GetParam().first,
        y = GetParam().second;

    XWarpPointer(Display(), 0, DefaultRootWindow(Display()), 0, 0, 0, 0, x, y);

    Window root, child;
    int rx, ry, wx, wy;
    unsigned int mask;

    XQueryPointer(Display(), DefaultRootWindow(Display()), &root, &child,
                  &rx, &ry, &wx, &wy, &mask);
    ASSERT_EQ(root, DefaultRootWindow(Display()));
    /* Warping to negative should clip to 0 */
    ASSERT_EQ(rx, std::max(x, 0));
    ASSERT_EQ(ry, std::max(y, 0));
}

INSTANTIATE_TEST_CASE_P(, SynapticsWarpTest,
                        ::testing::Values(std::make_pair(0, 0),
                                          std::make_pair(1, 1),
                                          std::make_pair(2, 2),
                                          std::make_pair(200, 200),
                                          std::make_pair(-1, -1)
                            ));

class SynapticsDriverClickpadTest : public InputDriverTest {
public:
    virtual void SetUp() {
        dev = std::auto_ptr<xorg::testing::evemu::Device>(
                new xorg::testing::evemu::Device(
                    RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.desc"
                    )
                );
        InputDriverTest::SetUp();
    }

    virtual void SetUpConfigAndLog(const std::string &param) {
        server.SetOption("-logfile", "/tmp/Xorg-synaptics-driver-clickpad.log");
        server.SetOption("-config", "/tmp/synaptics-clickpad.conf");

        config.AddDefaultScreenWithDriver();
        config.AddInputSection("synaptics", "--device--",
                               "Option \"CorePointer\"         \"on\"\n"
                               "Option \"GrabEventDevice\"     \"0\"\n"
                               "Option \"Device\"              \"" + dev->GetDeviceNode() + "\"\n");
        config.WriteConfig("/tmp/synaptics-clickpad.conf");
    }

protected:
    std::auto_ptr<xorg::testing::evemu::Device> dev;
};

TEST_F(SynapticsDriverClickpadTest, ClickpadProperties)
{
    int major = 2;
    int minor = 0;
    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));

    int deviceid;
    ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);

    Atom clickpad_prop = XInternAtom(Display(), "Synaptics ClickPad", True);
    ASSERT_NE(clickpad_prop, None);

    Status status;
    Atom type;
    int format;
    unsigned long nitems, bytes_after;
    unsigned char *data;

    status = XIGetProperty(Display(), deviceid, clickpad_prop, 0, 1, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 8);
    ASSERT_EQ(nitems, 1);
    ASSERT_EQ(bytes_after, 0);
    ASSERT_EQ(data[0], 1);
    free(data);

    /* This option is assigned by the xorg.conf.d, it won't activate for
       xorg.conf devices. */
    Atom softbutton_props = XInternAtom(Display(), "Synaptics Soft Button Areas", True);
    ASSERT_NE(softbutton_props, None);

    status = XIGetProperty(Display(), deviceid, softbutton_props, 0, 8, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 32);
    ASSERT_EQ(nitems, 8);
    ASSERT_EQ(bytes_after, 0);

    int32_t *buttons = reinterpret_cast<int32_t*>(data);
    ASSERT_EQ(buttons[0], 0);
    ASSERT_EQ(buttons[1], 0);
    ASSERT_EQ(buttons[2], 0);
    ASSERT_EQ(buttons[3], 0);
    ASSERT_EQ(buttons[4], 0);
    ASSERT_EQ(buttons[5], 0);
    ASSERT_EQ(buttons[6], 0);
    ASSERT_EQ(buttons[7], 0);

    free(data);

}

TEST(SynapticsClickPad, HotPlugSoftButtons)
{
    std::auto_ptr<xorg::testing::evemu::Device> dev;

    dev = std::auto_ptr<xorg::testing::evemu::Device>(
            new xorg::testing::evemu::Device(
                    RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.desc"
                )
            );

    XOrgConfig config;
    xorg::testing::XServer server;

    config.SetAutoAddDevices(true);
    config.AddDefaultScreenWithDriver();
    StartServer("synaptics-clickpad-softbuttons", server, config);

    ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
    int major = 2;
    int minor = 0;
    ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));

    int deviceid;
    int ndevices = FindInputDeviceByName(dpy, "SynPS/2 Synaptics TouchPad", &deviceid);
    ASSERT_GT(ndevices, 0);
    EXPECT_EQ(ndevices, 1) << "More than one touchpad found, cannot "
                              "guarantee right behaviour.";

    Atom clickpad_prop = XInternAtom(dpy, "Synaptics ClickPad", True);
    ASSERT_NE(clickpad_prop, None);

    Status status;
    Atom type;
    int format;
    unsigned long nitems, bytes_after;
    unsigned char *data;

    status = XIGetProperty(dpy, deviceid, clickpad_prop, 0, 1, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 8);
    ASSERT_EQ(nitems, 1);
    ASSERT_EQ(bytes_after, 0);
    ASSERT_EQ(data[0], 1);
    free(data);

    /* This option is assigned by the xorg.conf.d, it won't activate for
       xorg.conf devices. */
    Atom softbutton_props = XInternAtom(dpy, "Synaptics Soft Button Areas", True);
    ASSERT_NE(softbutton_props, None);

    status = XIGetProperty(dpy, deviceid, softbutton_props, 0, 8, False,
                           XIAnyPropertyType, &type, &format, &nitems,
                           &bytes_after, &data);

    ASSERT_EQ(status, Success);
    ASSERT_EQ(format, 32);
    ASSERT_EQ(nitems, 8);
    ASSERT_EQ(bytes_after, 0);

    int32_t *buttons = reinterpret_cast<int32_t*>(data);
    ASSERT_EQ(buttons[0], 3472);
    ASSERT_EQ(buttons[1], 0);
    ASSERT_EQ(buttons[2], 3900);
    ASSERT_EQ(buttons[3], 0);
    ASSERT_EQ(buttons[4], 0);
    ASSERT_EQ(buttons[5], 0);
    ASSERT_EQ(buttons[6], 0);
    ASSERT_EQ(buttons[7], 0);

    free(data);

    config.RemoveConfig();
    server.RemoveLogFile();
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "queue thread safe.hpp"
#include "gtest/gtest.h"
#include <thread>
#include <algorithm>
#include "aux_tests.hpp"

TEST(Push,HandleBasicOperation){
	std::threadsafe::queue<int> queue;

	int out;
	for (int i = 1;i <= 10;i++){
			queue.push(i);

			queue.wait_back(out);
			EXPECT_EQ(i,out);

			queue.wait_top(out);
			EXPECT_EQ(out,1);
			EXPECT_EQ(i,queue.size());
	}

	for (int i = 1;i <= 10;i++){
			queue.wait_pop(out);
			EXPECT_EQ(i,out);
			EXPECT_EQ(10-i,queue.size());
	}
}

TEST(Push,ThreadSafety){

	std::threadsafe::queue<int> queue;
	std::threadsafe::queue<int> another_queue;
	constexpr int ITERATIONS = 10;
	constexpr int PRODUCERS = ITERATIONS;
	constexpr int CONSUMERS = ITERATIONS;

	auto producer = [&](int id,int it){queue.push(id);};
	auto consumer = [&](int id,int it){
					int out;
					queue.wait_pop(out);
					ASSERT_LT(out,ITERATIONS);
					ASSERT_GE(out,0);
					another_queue.push(out);
					};

	launchThreads(producer,consumer,PRODUCERS,CONSUMERS,ITERATIONS);

	ASSERT_EQ(ITERATIONS*ITERATIONS,another_queue.size());

	int freq_table[ITERATIONS];
	std::fill(freq_table,freq_table+ITERATIONS,0);
	while (!another_queue.empty()){
		int out;
		another_queue.wait_pop(out);
		freq_table[out]++;
	}

	for (int i = 0;i < ITERATIONS;i++)
	{
		ASSERT_EQ(ITERATIONS,freq_table[i]);
	}
}

TEST(Push,UpperBound){
	std::threadsafe::queue<int> queue;
	constexpr int ITERATIONS_PRODUCERS = 10;
	constexpr int NUM_PRODUCERS = ITERATIONS_PRODUCERS;
	constexpr int NUM_CONSUMERS = 1;
	constexpr int SIZE = NUM_PRODUCERS/2;
	constexpr int ITERATIONS_CONSUMERS = ITERATIONS_PRODUCERS*NUM_PRODUCERS;
	queue.setLimit(SIZE);

	auto producer = [&](int id,int it){
				queue.push(id);
				ASSERT_LE(queue.size(),SIZE);
			};
	auto consumer = [&](int id,int it){
				int out;
				ASSERT_LE(queue.size(),SIZE);
				queue.wait_pop(out);
			};

	launchThreads(producer,consumer,NUM_PRODUCERS,NUM_CONSUMERS,ITERATIONS_PRODUCERS,ITERATIONS_CONSUMERS);
}
<commit_msg>Added test try_pop in queue<commit_after>#include "queue thread safe.hpp"
#include "gtest/gtest.h"
#include <thread>
#include <algorithm>
#include "aux_tests.hpp"

TEST(Push,HandleBasicOperation){
	std::threadsafe::queue<int> queue;

	int out;
	for (int i = 1;i <= 10;i++){
			queue.push(i);

			queue.wait_back(out);
			EXPECT_EQ(i,out);

			queue.wait_top(out);
			EXPECT_EQ(out,1);
			EXPECT_EQ(i,queue.size());
	}

	for (int i = 1;i <= 10;i++){
			queue.wait_pop(out);
			EXPECT_EQ(i,out);
			EXPECT_EQ(10-i,queue.size());
	}
}

TEST(Push,ThreadSafety){

	std::threadsafe::queue<int> queue;
	std::threadsafe::queue<int> another_queue;
	constexpr int ITERATIONS = 10;
	constexpr int PRODUCERS = ITERATIONS;
	constexpr int CONSUMERS = ITERATIONS;

	auto producer = [&](int id,int it){queue.push(id);};
	auto consumer = [&](int id,int it){
					int out;
					queue.wait_pop(out);
					ASSERT_LT(out,ITERATIONS);
					ASSERT_GE(out,0);
					another_queue.push(out);
					};

	launchThreads(producer,consumer,PRODUCERS,CONSUMERS,ITERATIONS);

	ASSERT_EQ(ITERATIONS*ITERATIONS,another_queue.size());

	int freq_table[ITERATIONS];
	std::fill(freq_table,freq_table+ITERATIONS,0);
	while (!another_queue.empty()){
		int out;
		another_queue.wait_pop(out);
		freq_table[out]++;
	}

	for (int i = 0;i < ITERATIONS;i++)
	{
		ASSERT_EQ(ITERATIONS,freq_table[i]);
	}
}

TEST(Push,UpperBound){
	std::threadsafe::queue<int> queue;
	constexpr int ITERATIONS_PRODUCERS = 10;
	constexpr int NUM_PRODUCERS = ITERATIONS_PRODUCERS;
	constexpr int NUM_CONSUMERS = 1;
	constexpr int SIZE = NUM_PRODUCERS/2;
	constexpr int ITERATIONS_CONSUMERS = ITERATIONS_PRODUCERS*NUM_PRODUCERS;
	queue.setLimit(SIZE);

	auto producer = [&](int id,int it){
				queue.push(id);
				ASSERT_LE(queue.size(),SIZE);
			};
	auto consumer = [&](int id,int it){
				int out;
				ASSERT_LE(queue.size(),SIZE);
				queue.wait_pop(out);
			};

	launchThreads(producer,consumer,NUM_PRODUCERS,NUM_CONSUMERS,ITERATIONS_PRODUCERS,ITERATIONS_CONSUMERS);
}

TEST(Try_pop,HandleBasicOperation){
	std::threadsafe::queue<int> queue;
	for (int i = 1;i <= 10;i++){
		queue.push(i);
	}

	int out;
	for (int i = 1;i <= 10;i++){
		ASSERT_EQ(10-i+1,queue.size());
		ASSERT_EQ(true,queue.try_pop(out));
		ASSERT_EQ(i,out);
	}
	ASSERT_EQ(0,queue.size());
	ASSERT_EQ(false,queue.try_pop(out));
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. 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.

// Tests for writing out the basic record types.

#include <sys/stat.h>
#include <string>

#include "gsf.h"
#include "gsf_ft.h"
#include "gsf_test_util.h"
#include "gtest/gtest.h"

namespace generic_sensor_format {
namespace test {
namespace {

TEST(GsfWriteSimple, HeaderOnly) {
  int handle;
  char filename[] = "sample-header-only.gsf";
  ASSERT_EQ(0, gsfOpen(filename, GSF_CREATE, &handle));
  ASSERT_EQ(0, gsfClose(handle));
  struct stat buf;
  ASSERT_EQ(0, stat(filename, &buf));
  ASSERT_EQ(24, buf.st_size);
}

void ValidateWriteComment(const char *filename,
                          bool checksum,
                          int expected_write_size,
                          const char *comment,
                          int expected_file_size) {
  ASSERT_NE(nullptr, filename);
  ASSERT_GE(expected_write_size, 20);
  ASSERT_NE(nullptr, comment);
  ASSERT_GE(expected_file_size, 44);

  int handle;
  ASSERT_EQ(0, gsfOpen(filename, GSF_CREATE, &handle));

  gsfDataID data_id = {checksum, 0, GSF_RECORD_COMMENT, 0};
  gsfRecords record;
  record.comment.comment_time.tv_sec = 1;
  record.comment.comment_time.tv_nsec = 2;
  record.comment.comment_length = strlen(comment);
  record.comment.comment = const_cast<char *>(comment);
  ASSERT_EQ(expected_write_size, gsfWrite(handle, &data_id, &record));

  ASSERT_EQ(0, gsfClose(handle));

  struct stat buf;
  ASSERT_EQ(0, stat(filename, &buf));
  ASSERT_EQ(expected_file_size, buf.st_size);
}

TEST(GsfWriteSimple, CommentEmpty) {
  char filename[] = "sample-comment-empty.gsf";
  char comment[] = "";
  ValidateWriteComment(filename, false, 20, comment, 44);
}

TEST(GsfWriteSimple, CommentEmptyChecksum) {
  char filename[] = "sample-comment-empty-checksum.gsf";
  char comment[] = "";
  ValidateWriteComment(filename, true, 24, comment, 48);
}

}  // namespace
}  // namespace test
}  // namespace generic_sensor_format
<commit_msg>Write comments with 1-5 characters and start reading back resulting gsf files.<commit_after>// Copyright 2015 Google Inc. 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.

// Tests for writing out the basic record types.

#include <sys/stat.h>
#include <string>

#include "gsf.h"
#include "gsf_ft.h"
#include "gsf_test_util.h"
#include "gtest/gtest.h"

namespace generic_sensor_format {
namespace test {
namespace {

TEST(GsfWriteSimple, HeaderOnly) {
  int handle;
  char filename[] = "sample-header-only.gsf";
  ASSERT_EQ(0, gsfOpen(filename, GSF_CREATE, &handle));
  ASSERT_EQ(0, gsfClose(handle));
  struct stat buf;
  ASSERT_EQ(0, stat(filename, &buf));
  ASSERT_EQ(24, buf.st_size);
}

void ValidateWriteComment(const char *filename,
                          bool checksum,
                          int expected_write_size,
                          const char *comment,
                          int expected_file_size) {
  ASSERT_NE(nullptr, filename);
  ASSERT_GE(expected_write_size, 20);
  ASSERT_NE(nullptr, comment);
  ASSERT_GE(expected_file_size, 44);

  int handle;
  ASSERT_EQ(0, gsfOpen(filename, GSF_CREATE, &handle));

  gsfDataID data_id = {checksum, 0, GSF_RECORD_COMMENT, 0};
  gsfRecords record;
  record.comment.comment_time.tv_sec = 1;
  record.comment.comment_time.tv_nsec = 2;
  record.comment.comment_length = strlen(comment);
  record.comment.comment = const_cast<char *>(comment);
  ASSERT_EQ(expected_write_size, gsfWrite(handle, &data_id, &record));

  ASSERT_EQ(0, gsfClose(handle));

  struct stat buf;
  ASSERT_EQ(0, stat(filename, &buf));
  ASSERT_EQ(expected_file_size, buf.st_size);

  ASSERT_EQ(0, gsfOpen(filename, GSF_READONLY, &handle));
  ASSERT_GE(handle, 0);
  int num_bytes;
  num_bytes = gsfRead(handle, GSF_NEXT_RECORD, &data_id, &record, nullptr, 0);
  ASSERT_EQ(expected_write_size, num_bytes);
  ASSERT_EQ(GSF_RECORD_COMMENT, data_id.recordID);
}

TEST(GsfWriteSimple, CommentEmpty) {
  char filename[] = "sample-comment-empty.gsf";
  char comment[] = "";
  ValidateWriteComment(filename, false, 20, comment, 44);
}

TEST(GsfWriteSimple, CommentEmptyChecksum) {
  char filename[] = "sample-comment-empty-checksum.gsf";
  char comment[] = "";
  ValidateWriteComment(filename, true, 24, comment, 48);
}

TEST(GsfWriteSimple, CommentUpTo5) {
  char filename1[] = "sample-comment-1.gsf";
  char comment1[] = "a";
  ValidateWriteComment(filename1, false, 24, comment1, 48);
  char filename2[] = "sample-comment-2.gsf";
  char comment2[] = "ab";
  ValidateWriteComment(filename2, false, 24, comment2, 48);
  char filename3[] = "sample-comment-3.gsf";
  char comment3[] = "abc";
  ValidateWriteComment(filename3, false, 24, comment3, 48);
  char filename4[] = "sample-comment-4.gsf";
  char comment4[] = "abcd";
  ValidateWriteComment(filename4, false, 24, comment4, 48);
  char filename5[] = "sample-comment-5.gsf";
  char comment5[] = "abcde";
  ValidateWriteComment(filename5, false, 28, comment5, 52);
}

}  // namespace
}  // namespace test
}  // namespace generic_sensor_format
<|endoftext|>


<commit_before>/*
 *            Copyright 2009-2017 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      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 <votca/xtp/numerical_integrations.h>
#include <votca/ctp/logger.h>
#include <votca/xtp/espfit.h>
#include <votca/xtp/aomatrix.h>
#include <votca/tools/linalg.h>
//#include <boost/progress.hpp>

#include <math.h>
#include <votca/tools/constants.h>

using namespace votca::tools;

namespace votca { namespace xtp {
    namespace ub = boost::numeric::ublas;

void Espfit::Fit2Density(std::vector< QMAtom* >& _atomlist, ub::matrix<double> &_dmat, AOBasis &_basis,string gridsize) {

    // setting up grid
    Grid _grid;
    _grid.setAtomlist(&_atomlist);
    _grid.setupCHELPgrid();
    //_grid.printGridtoxyzfile("grid.xyz");
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() <<  " Done setting up CHELPG grid with " << _grid.getsize() << " points " << flush;

    // Calculating nuclear potential at gridpoints

    ub::vector<double> _ESPatGrid = ub::zero_vector<double>(_grid.getsize());

    AOOverlap overlap;
    overlap.Fill(_basis);
    ub::vector<double> DMATasarray=_dmat.data();
    ub::vector<double> AOOasarray=overlap.Matrix().data();
    double N_comp=0.0;
    #pragma omp parallel for reduction(+:N_comp)
    for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            N_comp =N_comp+ DMATasarray(_i)*AOOasarray(_i);
        }

    NumericalIntegration numway;

    numway.GridSetup(gridsize,_atomlist,&_basis);
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Setup "<<gridsize<<" Numerical Grid with "<<numway.getGridSize()<<" gridpoints."<< flush;
    double N=numway.IntegrateDensity(_dmat);
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculated Densities at Numerical Grid, Number of electrons is "<< N << flush;

    if(std::abs(N-N_comp)>0.001){
        CTP_LOG(ctp::logDEBUG, *_log) <<"=======================" << flush;
        CTP_LOG(ctp::logDEBUG, *_log) <<"WARNING: Calculated Densities at Numerical Grid, Number of electrons "<< N <<" is far away from the the real value "<< N_comp<<", you should increase the accuracy of the integration grid."<< flush;
        N=N_comp;
        CTP_LOG(ctp::logDEBUG, *_log) <<"WARNING: Electronnumber set to "<< N << flush;
        CTP_LOG(ctp::logDEBUG, *_log) <<"=======================" << flush;
    }

    double netcharge=getNetcharge( _atomlist,N );

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP at CHELPG grid points"  << flush;
    //boost::progress_display show_progress( _grid.getsize() );
    #pragma omp parallel for
<<<<<<< HEAD
    for ( unsigned i = 0 ; i < _grid.getsize(); i++){
=======
    for ( unsigned int i = 0 ; i < _grid.getsize(); i++){
>>>>>>> fc32ec7d18c290b005462342e604b450817c3563
        _ESPatGrid(i)=numway.IntegratePotential(_grid.getGrid()[i]);
        //++show_progress;
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Electron contribution calculated"  << flush;
    if (!_do_Transition){
    ub::vector<double> _NucPatGrid = EvalNuclearPotential(  _atomlist,  _grid );
    _ESPatGrid += _NucPatGrid;
    }

    std::vector< tools::vec > _fitcenters;

    for ( unsigned j = 0; j < _atomlist.size(); j++){
       tools::vec _pos=_atomlist[j]->getPos();
      _fitcenters.push_back(_pos);
    }

    std::vector<double> _charges = FitPartialCharges(_fitcenters,_grid, _ESPatGrid, netcharge);

    //Write charges to qmatoms
    for ( unsigned _i =0 ; _i < _atomlist.size(); _i++){
        _atomlist[_i]->setPartialcharge(_charges[_i]);
    }
    return;
    }

ub::vector<double> Espfit::EvalNuclearPotential(std::vector< QMAtom* >& _atoms, Grid _grid) {
    ub::vector<double> _NucPatGrid = ub::zero_vector<double>(_grid.getsize());

<<<<<<< HEAD

=======
>>>>>>> fc32ec7d18c290b005462342e604b450817c3563
    const std::vector< vec >& _gridpoints = _grid.getGrid();
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP of nuclei at CHELPG grid points" << flush;

    for (unsigned i = 0; i < _gridpoints.size(); i++) {
        for (unsigned j = 0; j < _atoms.size(); j++) {
            const vec& posatom=_atoms[j]->getPos();
            double Znuc=_atoms[j]->getNuccharge();
            double dist_j = tools::abs(_gridpoints[i]-posatom);
            _NucPatGrid(i) += Znuc / dist_j;
        }

    }
    return _NucPatGrid;
}

double Espfit::getNetcharge( std::vector< QMAtom* >& _atoms, double N ){
    double netcharge = 0.0;
      if (std::abs(N) < 0.05) {
        CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Number of Electrons is " << N << " transitiondensity is used for fit" << flush;
        _do_Transition = true;
      } else {

        double Znuc = 0.0;
        for (unsigned j = 0; j < _atoms.size(); j++) {
          Znuc += _atoms[j]->getNuccharge();
        }

        if (std::abs(Znuc - N) < 4) {
          CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Number of Electrons minus Nucleus charge is " << Znuc - N << "." << flush;
        } else {
          CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Warning: Your molecule is highly ionized." << flush;
        }
        netcharge = Znuc - N;
        _do_Transition = false;
      }

      netcharge = round(netcharge);
      CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Netcharge constrained to " << netcharge << flush;

      return netcharge;
}

void Espfit::Fit2Density_analytic(std::vector< QMAtom* >& _atomlist, ub::matrix<double> &_dmat,AOBasis &_basis) {
    // setting up grid
    Grid _grid;
    _grid.setAtomlist(&_atomlist);
    _grid.setupCHELPgrid();

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() <<  " Done setting up CHELPG grid with " << _grid.getsize() << " points " << endl;
    // Calculating nuclear potential at gridpoints

    ub::vector<double> _ESPatGrid = ub::zero_vector<double>(_grid.getsize());

    AOOverlap overlap;
    overlap.Fill(_basis);
    const ub::vector<double> DMATasarray=_dmat.data();
    const ub::vector<double> AOOasarray=overlap.Matrix().data();
    double N=0.0;
    #pragma omp parallel for reduction(+:N)
    for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            N =N+ DMATasarray(_i)*AOOasarray(_i);
        }

    double netcharge=getNetcharge( _atomlist,N );
    if(!_do_Transition){
        ub::vector<double> _NucPatGrid = EvalNuclearPotential(  _atomlist,  _grid);
        _ESPatGrid += _NucPatGrid;
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP at CHELPG grid points"  << flush;
    #pragma omp parallel for
    for ( unsigned i = 0 ; i < _grid.getsize(); i++){
        // AOESP matrix
         AOESP _aoesp;
         _aoesp.Fill(_basis, _grid.getGrid()[i]);
        const ub::vector<double> AOESPasarray=_aoesp.Matrix().data();

        for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            _ESPatGrid(i) -= DMATasarray(_i)*AOESPasarray(_i);
        }
    }

    std::vector< tools::vec > _fitcenters;

          for ( unsigned j = 0; j < _atomlist.size(); j++){
             tools::vec _pos=_atomlist[j]->getPos();
            _fitcenters.push_back(_pos);
          }
    std::vector<double> _charges = FitPartialCharges(_fitcenters,_grid, _ESPatGrid, netcharge);

    //Write charges to qmatoms
        for ( unsigned _i =0 ; _i < _atomlist.size(); _i++){
            _atomlist[_i]->setPartialcharge(_charges[_i]);
        }
    return;
    }

std::vector<double> Espfit::FitPartialCharges( std::vector< tools::vec >& _fitcenters, Grid& _grid, ub::vector<double>& _potential, double& _netcharge ){
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Setting up Matrices for fitting of size "<< _fitcenters.size()+1 <<" x " << _fitcenters.size()+1<< flush;

    const std::vector< tools::vec >& _gridpoints=_grid.getGrid();

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Using "<< _fitcenters.size() <<" Fittingcenters and " << _gridpoints.size()<< " Gridpoints."<< flush;

    ub::matrix<double> _Amat = ub::zero_matrix<double>(_fitcenters.size()+1,_fitcenters.size()+1);
    ub::matrix<double> _Bvec = ub::zero_matrix<double>(_fitcenters.size()+1,1);
    //boost::progress_display show_progress( _fitcenters.size() );
    // setting up _Amat
    #pragma omp parallel for
    for ( unsigned _i =0 ; _i < _Amat.size1()-1; _i++){
        for ( unsigned _j=_i; _j<_Amat.size2()-1; _j++){
            for ( unsigned _k=0; _k < _gridpoints.size(); _k++){
                double dist_i = tools::abs(_fitcenters[_i]-_gridpoints[_k]);
                double dist_j = tools::abs(_fitcenters[_j]-_gridpoints[_k]);

                 _Amat(_i,_j) += 1.0/dist_i/dist_j;
            }
            _Amat(_j,_i) = _Amat(_i,_j);
        }
    }

    for ( unsigned _i =0 ; _i < _Amat.size1(); _i++){
      _Amat(_i,_Amat.size1()-1) = 1.0;
      _Amat(_Amat.size1()-1,_i) = 1.0;
    }
    _Amat(_Amat.size1()-1,_Amat.size1()-1) = 0.0;

    // setting up Bvec
    #pragma omp parallel for
    for ( unsigned _i =0 ; _i < _Bvec.size1()-1; _i++){
        for ( unsigned _k=0; _k < _gridpoints.size(); _k++){
                double dist_i = tools::abs(_fitcenters[_i]-_gridpoints[_k]);
                _Bvec(_i,0) += _potential(_k)/dist_i;
        }
       }

    _Bvec(_Bvec.size1()-1,0) = _netcharge; //netcharge!!!!
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Inverting Matrices "<< flush;
    // invert _Amat
    ub::matrix<double> _Amat_inverse = ub::zero_matrix<double>(_fitcenters.size()+1,_fitcenters.size()+1);

    if(_do_svd){
        int notfittedatoms=linalg_invert_svd( _Amat , _Amat_inverse,_conditionnumber);
        CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << "SVD Done. "<<notfittedatoms<<" could not be fitted and are set to zero."<< flush;
    }
    else{
        linalg_invert( _Amat , _Amat_inverse);
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Inverting Matrices done."<< flush;
    //_Amat.resize(0,0);

    ub::matrix<double> _charges = ub::prod(_Amat_inverse,_Bvec);

    std::vector<double> _result;
    for ( unsigned _i = 0; _i < _charges.size1(); _i++ ){
        _result.push_back(_charges(_i,0));
    }

    double _sumcrg = 0.0;
    for ( unsigned _i =0 ; _i < _fitcenters.size(); _i++){

        //CTP_LOG(ctp::logDEBUG, *_log) << " Center " << _i << " FitCharge: " << _result[_i] << "pos " << _fitcenters[_i] << flush;
        _sumcrg += _result[_i];
    }

    CTP_LOG(ctp::logDEBUG, *_log) << " Sum of fitted charges: " << _sumcrg << flush;

    // get RMSE
    double _rmse = 0.0;
    double _totalPotSq = 0.0;
    for ( unsigned _k=0 ; _k < _gridpoints.size(); _k++ ){
        double temp = 0.0;
        for ( unsigned _i=0; _i < _fitcenters.size(); _i++ ){
            double dist =  tools::abs(_gridpoints[_k]-_fitcenters[_i]);
            temp += _result[_i]/dist;
        }
        _rmse += (_potential(_k) - temp)*(_potential(_k) - temp);
        _totalPotSq += _potential(_k)*_potential(_k);
    }
    CTP_LOG(ctp::logDEBUG, *_log) << " RMSE of fit:  " << sqrt(_rmse/_gridpoints.size()) << flush;
    CTP_LOG(ctp::logDEBUG, *_log) << " RRMSE of fit: " << sqrt(_rmse/_totalPotSq) << flush;

    return _result;
   }

}}
<commit_msg>Fixed merge conflict with development branch<commit_after>/*
 *            Copyright 2009-2017 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      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 <votca/xtp/numerical_integrations.h>
#include <votca/ctp/logger.h>
#include <votca/xtp/espfit.h>
#include <votca/xtp/aomatrix.h>
#include <votca/tools/linalg.h>
//#include <boost/progress.hpp>

#include <math.h>
#include <votca/tools/constants.h>

using namespace votca::tools;

namespace votca { namespace xtp {
    namespace ub = boost::numeric::ublas;

void Espfit::Fit2Density(std::vector< QMAtom* >& _atomlist, ub::matrix<double> &_dmat, AOBasis &_basis,string gridsize) {

    // setting up grid
    Grid _grid;
    _grid.setAtomlist(&_atomlist);
    _grid.setupCHELPgrid();
    //_grid.printGridtoxyzfile("grid.xyz");
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() <<  " Done setting up CHELPG grid with " << _grid.getsize() << " points " << flush;

    // Calculating nuclear potential at gridpoints

    ub::vector<double> _ESPatGrid = ub::zero_vector<double>(_grid.getsize());

    AOOverlap overlap;
    overlap.Fill(_basis);
    ub::vector<double> DMATasarray=_dmat.data();
    ub::vector<double> AOOasarray=overlap.Matrix().data();
    double N_comp=0.0;
    #pragma omp parallel for reduction(+:N_comp)
    for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            N_comp =N_comp+ DMATasarray(_i)*AOOasarray(_i);
        }

    NumericalIntegration numway;

    numway.GridSetup(gridsize,_atomlist,&_basis);
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Setup "<<gridsize<<" Numerical Grid with "<<numway.getGridSize()<<" gridpoints."<< flush;
    double N=numway.IntegrateDensity(_dmat);
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculated Densities at Numerical Grid, Number of electrons is "<< N << flush;

    if(std::abs(N-N_comp)>0.001){
        CTP_LOG(ctp::logDEBUG, *_log) <<"=======================" << flush;
        CTP_LOG(ctp::logDEBUG, *_log) <<"WARNING: Calculated Densities at Numerical Grid, Number of electrons "<< N <<" is far away from the the real value "<< N_comp<<", you should increase the accuracy of the integration grid."<< flush;
        N=N_comp;
        CTP_LOG(ctp::logDEBUG, *_log) <<"WARNING: Electronnumber set to "<< N << flush;
        CTP_LOG(ctp::logDEBUG, *_log) <<"=======================" << flush;
    }

    double netcharge=getNetcharge( _atomlist,N );

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP at CHELPG grid points"  << flush;
    //boost::progress_display show_progress( _grid.getsize() );
    #pragma omp parallel for
    for ( unsigned i = 0 ; i < _grid.getsize(); i++){
        _ESPatGrid(i)=numway.IntegratePotential(_grid.getGrid()[i]);
        //++show_progress;
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Electron contribution calculated"  << flush;
    if (!_do_Transition){
    ub::vector<double> _NucPatGrid = EvalNuclearPotential(  _atomlist,  _grid );
    _ESPatGrid += _NucPatGrid;
    }

    std::vector< tools::vec > _fitcenters;

    for ( unsigned j = 0; j < _atomlist.size(); j++){
       tools::vec _pos=_atomlist[j]->getPos();
      _fitcenters.push_back(_pos);
    }

    std::vector<double> _charges = FitPartialCharges(_fitcenters,_grid, _ESPatGrid, netcharge);

    //Write charges to qmatoms
    for ( unsigned _i =0 ; _i < _atomlist.size(); _i++){
        _atomlist[_i]->setPartialcharge(_charges[_i]);
    }
    return;
    }

ub::vector<double> Espfit::EvalNuclearPotential(std::vector< QMAtom* >& _atoms, Grid _grid) {
    ub::vector<double> _NucPatGrid = ub::zero_vector<double>(_grid.getsize());

<<<<<<< HEAD

=======
>>>>>>> fc32ec7d18c290b005462342e604b450817c3563
    const std::vector< vec >& _gridpoints = _grid.getGrid();
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP of nuclei at CHELPG grid points" << flush;

    for (unsigned i = 0; i < _gridpoints.size(); i++) {
        for (unsigned j = 0; j < _atoms.size(); j++) {
            const vec& posatom=_atoms[j]->getPos();
            double Znuc=_atoms[j]->getNuccharge();
            double dist_j = tools::abs(_gridpoints[i]-posatom);
            _NucPatGrid(i) += Znuc / dist_j;
        }

    }
    return _NucPatGrid;
}

double Espfit::getNetcharge( std::vector< QMAtom* >& _atoms, double N ){
    double netcharge = 0.0;
      if (std::abs(N) < 0.05) {
        CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Number of Electrons is " << N << " transitiondensity is used for fit" << flush;
        _do_Transition = true;
      } else {

        double Znuc = 0.0;
        for (unsigned j = 0; j < _atoms.size(); j++) {
          Znuc += _atoms[j]->getNuccharge();
        }

        if (std::abs(Znuc - N) < 4) {
          CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Number of Electrons minus Nucleus charge is " << Znuc - N << "." << flush;
        } else {
          CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Warning: Your molecule is highly ionized." << flush;
        }
        netcharge = Znuc - N;
        _do_Transition = false;
      }

      netcharge = round(netcharge);
      CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp()<< " Netcharge constrained to " << netcharge << flush;

      return netcharge;
}

void Espfit::Fit2Density_analytic(std::vector< QMAtom* >& _atomlist, ub::matrix<double> &_dmat,AOBasis &_basis) {
    // setting up grid
    Grid _grid;
    _grid.setAtomlist(&_atomlist);
    _grid.setupCHELPgrid();

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() <<  " Done setting up CHELPG grid with " << _grid.getsize() << " points " << endl;
    // Calculating nuclear potential at gridpoints

    ub::vector<double> _ESPatGrid = ub::zero_vector<double>(_grid.getsize());

    AOOverlap overlap;
    overlap.Fill(_basis);
    const ub::vector<double> DMATasarray=_dmat.data();
    const ub::vector<double> AOOasarray=overlap.Matrix().data();
    double N=0.0;
    #pragma omp parallel for reduction(+:N)
    for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            N =N+ DMATasarray(_i)*AOOasarray(_i);
        }

    double netcharge=getNetcharge( _atomlist,N );
    if(!_do_Transition){
        ub::vector<double> _NucPatGrid = EvalNuclearPotential(  _atomlist,  _grid);
        _ESPatGrid += _NucPatGrid;
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Calculating ESP at CHELPG grid points"  << flush;
    #pragma omp parallel for
    for ( unsigned i = 0 ; i < _grid.getsize(); i++){
        // AOESP matrix
         AOESP _aoesp;
         _aoesp.Fill(_basis, _grid.getGrid()[i]);
        const ub::vector<double> AOESPasarray=_aoesp.Matrix().data();

        for ( unsigned _i =0; _i < DMATasarray.size(); _i++ ){
            _ESPatGrid(i) -= DMATasarray(_i)*AOESPasarray(_i);
        }
    }

    std::vector< tools::vec > _fitcenters;

          for ( unsigned j = 0; j < _atomlist.size(); j++){
             tools::vec _pos=_atomlist[j]->getPos();
            _fitcenters.push_back(_pos);
          }
    std::vector<double> _charges = FitPartialCharges(_fitcenters,_grid, _ESPatGrid, netcharge);

    //Write charges to qmatoms
        for ( unsigned _i =0 ; _i < _atomlist.size(); _i++){
            _atomlist[_i]->setPartialcharge(_charges[_i]);
        }
    return;
    }

std::vector<double> Espfit::FitPartialCharges( std::vector< tools::vec >& _fitcenters, Grid& _grid, ub::vector<double>& _potential, double& _netcharge ){
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Setting up Matrices for fitting of size "<< _fitcenters.size()+1 <<" x " << _fitcenters.size()+1<< flush;

    const std::vector< tools::vec >& _gridpoints=_grid.getGrid();

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Using "<< _fitcenters.size() <<" Fittingcenters and " << _gridpoints.size()<< " Gridpoints."<< flush;

    ub::matrix<double> _Amat = ub::zero_matrix<double>(_fitcenters.size()+1,_fitcenters.size()+1);
    ub::matrix<double> _Bvec = ub::zero_matrix<double>(_fitcenters.size()+1,1);
    //boost::progress_display show_progress( _fitcenters.size() );
    // setting up _Amat
    #pragma omp parallel for
    for ( unsigned _i =0 ; _i < _Amat.size1()-1; _i++){
        for ( unsigned _j=_i; _j<_Amat.size2()-1; _j++){
            for ( unsigned _k=0; _k < _gridpoints.size(); _k++){
                double dist_i = tools::abs(_fitcenters[_i]-_gridpoints[_k]);
                double dist_j = tools::abs(_fitcenters[_j]-_gridpoints[_k]);

                 _Amat(_i,_j) += 1.0/dist_i/dist_j;
            }
            _Amat(_j,_i) = _Amat(_i,_j);
        }
    }

    for ( unsigned _i =0 ; _i < _Amat.size1(); _i++){
      _Amat(_i,_Amat.size1()-1) = 1.0;
      _Amat(_Amat.size1()-1,_i) = 1.0;
    }
    _Amat(_Amat.size1()-1,_Amat.size1()-1) = 0.0;

    // setting up Bvec
    #pragma omp parallel for
    for ( unsigned _i =0 ; _i < _Bvec.size1()-1; _i++){
        for ( unsigned _k=0; _k < _gridpoints.size(); _k++){
                double dist_i = tools::abs(_fitcenters[_i]-_gridpoints[_k]);
                _Bvec(_i,0) += _potential(_k)/dist_i;
        }
       }

    _Bvec(_Bvec.size1()-1,0) = _netcharge; //netcharge!!!!
    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Inverting Matrices "<< flush;
    // invert _Amat
    ub::matrix<double> _Amat_inverse = ub::zero_matrix<double>(_fitcenters.size()+1,_fitcenters.size()+1);

    if(_do_svd){
        int notfittedatoms=linalg_invert_svd( _Amat , _Amat_inverse,_conditionnumber);
        CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << "SVD Done. "<<notfittedatoms<<" could not be fitted and are set to zero."<< flush;
    }
    else{
        linalg_invert( _Amat , _Amat_inverse);
    }

    CTP_LOG(ctp::logDEBUG, *_log) << ctp::TimeStamp() << " Inverting Matrices done."<< flush;
    //_Amat.resize(0,0);

    ub::matrix<double> _charges = ub::prod(_Amat_inverse,_Bvec);

    std::vector<double> _result;
    for ( unsigned _i = 0; _i < _charges.size1(); _i++ ){
        _result.push_back(_charges(_i,0));
    }

    double _sumcrg = 0.0;
    for ( unsigned _i =0 ; _i < _fitcenters.size(); _i++){

        //CTP_LOG(ctp::logDEBUG, *_log) << " Center " << _i << " FitCharge: " << _result[_i] << "pos " << _fitcenters[_i] << flush;
        _sumcrg += _result[_i];
    }

    CTP_LOG(ctp::logDEBUG, *_log) << " Sum of fitted charges: " << _sumcrg << flush;

    // get RMSE
    double _rmse = 0.0;
    double _totalPotSq = 0.0;
    for ( unsigned _k=0 ; _k < _gridpoints.size(); _k++ ){
        double temp = 0.0;
        for ( unsigned _i=0; _i < _fitcenters.size(); _i++ ){
            double dist =  tools::abs(_gridpoints[_k]-_fitcenters[_i]);
            temp += _result[_i]/dist;
        }
        _rmse += (_potential(_k) - temp)*(_potential(_k) - temp);
        _totalPotSq += _potential(_k)*_potential(_k);
    }
    CTP_LOG(ctp::logDEBUG, *_log) << " RMSE of fit:  " << sqrt(_rmse/_gridpoints.size()) << flush;
    CTP_LOG(ctp::logDEBUG, *_log) << " RRMSE of fit: " << sqrt(_rmse/_totalPotSq) << flush;

    return _result;
   }

}}
<|endoftext|>