<commit_before> //
//  Character.cpp
//  jamPewDiePie
//
//  Created by rustray on 21.11.14.
//
//

#include "Character.h"

using namespace cocos2d;

Character* Character::create(const std::string& filename)
{
    Character *sprite = new (std::nothrow) Character();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

Character::Character(){

}

void Character::onEnter(){
    Sprite::onEnter();
    _target = Vec2(1000,0);
    goToTarget();
    scheduleUpdate();
}

void Character::createBody(){
    PhysicsMaterial material(100,0.15f,1.1f);
    PhysicsBody* body = PhysicsBody::createBox(this->getContentSize(), material);
    this->setPhysicsBody(body);
}

void Character::setBottom(cocos2d::PhysicsBody* body){
    body->setContactTestBitmask(0xFFFFFFFF);
    this->getPhysicsBody()->setContactTestBitmask(0xFFFFFFFF);
    auto contactListener = EventListenerPhysicsContactWithBodies::create(this->getPhysicsBody(), body);
    contactListener->onContactBegin = CC_CALLBACK_1(Character::onContactBegin, this);
    contactListener->onContactPostSolve = [=](PhysicsContact& contact, const PhysicsContactPostSolve& solve)
    {
        _isContactGround = true;
    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
}

void Character::update(float dt){
    if(_isContactGround)
        setColor(Color3B(255,0,0));
    else
        setColor(Color3B(255,255,255));
    goToTarget();
    _isContactGround = false;
}

bool Character::onContactBegin(PhysicsContact& contact){
    log("onContactBegin");
    return true;
}

void Character::setTarget(Vec2 point){
    _target = point;
}

void Character::goToTarget(){
//    Vec2 delta = _target - this->getPosition();
//    delta.normalize();
//    this->setPosition(this->getPosition() + delta * 3);
    if(_isContactGround){
        if()
        Vec2 velocity = this->getPhysicsBody()->getVelocity() + Vec2(10,0);
        this->getPhysicsBody()->setVelocity(velocity);
    }
};

<commit_msg>КОКОКО<commit_after> //
//  Character.cpp
//  jamPewDiePie
//
//  Created by rustray on 21.11.14.
//
//

#include "Character.h"

using namespace cocos2d;

Character* Character::create(const std::string& filename)
{
    Character *sprite = new (std::nothrow) Character();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

Character::Character(){

}

void Character::onEnter(){
    Sprite::onEnter();
    _target = Vec2(200,0);
    goToTarget();
    scheduleUpdate();
}

void Character::createBody(){
    PhysicsMaterial material(100, 0.15f, 0.1f);
    PhysicsBody* body = PhysicsBody::createBox(this->getContentSize(), material);
    this->setPhysicsBody(body);
}

void Character::setBottom(cocos2d::PhysicsBody* body){
    body->setContactTestBitmask(0xFFFFFFFF);
    this->getPhysicsBody()->setContactTestBitmask(0xFFFFFFFF);
    auto contactListener = EventListenerPhysicsContactWithBodies::create(this->getPhysicsBody(), body);
    contactListener->onContactBegin = CC_CALLBACK_1(Character::onContactBegin, this);
    contactListener->onContactPostSolve = [=](PhysicsContact& contact, const PhysicsContactPostSolve& solve)
    {
        _isContactGround = true;
    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
}

void Character::update(float dt){
    if(_isContactGround)
        setColor(Color3B(255,0,0));
    else
        setColor(Color3B(255,255,255));
    goToTarget();
    _isContactGround = false;
}

bool Character::onContactBegin(PhysicsContact& contact){
    log("onContactBegin");
    return true;
}

void Character::setTarget(Vec2 point){
    _target = point;
}

void Character::goToTarget(){

	Vec2 velocity = this->getPhysicsBody()->getVelocity();
	CCLOG("velocity: %f\n", velocity.x);

	//   .
    Vec2 delta = _target - this->getPosition();
	delta.y = 0;

	float targetSpeed = (delta.x < 1) ? 0 : 300;

	delta.normalize();
	delta.rotate(Vec2(), CC_DEGREES_TO_RADIANS(-this->getParent()->getRotation()));
	targetSpeed *= delta.x;

	float impulse = targetSpeed - velocity.x;
	impulse *= this->getPhysicsBody()->getMass();
	this->getPhysicsBody()->applyImpulse(Vec2(impulse, 0));
	return;
};
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//____________________________________________________________________
//
// This is a class that constructs AliFMDMult (reconstructed
// multiplicity) from of Digits
//
// This class reads either digits from a TClonesArray or raw data from
// a DDL file (or similar), and stores the read ADC counts in an
// internal cache (fAdcs).
//
// From the cached values it then calculates the number of particles
// that hit a region of the FMDs, as specified by the user.
//
// The reconstruction can be done in two ways: Either via counting the
// number of empty strips (Poisson method), or by converting the ADC
// signal to an energy deposition, and then dividing by the typical
// energy loss of a particle.
//
//      +---------------------+       +---------------------+
//      | AliFMDReconstructor |<>-----| AliFMDMultAlgorithm |
//      +---------------------+       +---------------------+
//                                               ^
//                                               |
//                                   +-----------+---------+
//                                   |                     |
//                         +-------------------+   +------------------+
//                         | AliFMDMultPoisson |   | AliFMDMultNaiive |
//                         +-------------------+   +------------------+
//
// AliFMDReconstructor acts as a manager class.  It contains a list of
// AliFMDMultAlgorithm objects.  The call graph looks something like
//
//
//       +----------------------+            +----------------------+
//       | :AliFMDReconstructor |            | :AliFMDMultAlgorithm |
//       +----------------------+            +----------------------+
//                  |                                  |
//    Reconstruct  +-+                                 |
//    ------------>| |                         PreRun +-+
//                 | |------------------------------->| |
//                 | |                                +-+
//                 | |-----+ (for each event)          |
//                 | |     | *ProcessEvent             |
//                 |+-+    |                           |
//                 || |<---+                 PreEvent +-+
//                 || |------------------------------>| |
//                 || |                               +-+
//                 || |-----+                          |
//                 || |     | ProcessDigits            |
//                 ||+-+    |                          |
//                 ||| |<---+                          |
//                 ||| |         *ProcessDigit(digit) +-+
//                 ||| |----------------------------->| |
//                 ||| |                              +-+
//                 ||+-+                               |
//                 || |                     PostEvent +-+
//                 || |------------------------------>| |
//                 || |                               +-+
//                 |+-+                                |
//                 | |                        PostRun +-+
//                 | |------------------------------->| |
//                 | |                                +-+
//                 +-+                                 |
//                  |                                  |
//
//
//
//-- Authors: Evgeny Karpechev(INR) and Alla Maevsksia
//  Latest changes by Christian Holm Christensen <cholm@nbi.dk>
//
//
//____________________________________________________________________

#include <AliLog.h>                        // ALILOG_H
#include <AliRun.h>                        // ALIRUN_H
#include <AliRunLoader.h>                  // ALIRUNLOADER_H
#include <AliLoader.h>                     // ALILOADER_H
#include <AliHeader.h>                     // ALIHEADER_H
#include <AliRawReader.h>                  // ALIRAWREADER_H
#include <AliGenEventHeader.h>             // ALIGENEVENTHEADER_H
#include "AliFMD.h"         		   // ALIFMD_H
#include "AliFMDGeometry.h"                // ALIFMDGEOMETRY_H
#include "AliFMDParameters.h"              // ALIFMDPARAMETERS_H
#include "AliFMDDetector.h"                // ALIFMDDETECTOR_H
#include "AliFMDRing.h"                    // ALIFMDRING_H
#include "AliFMDDigit.h"                   // ALIFMDDIGIT_H
#include "AliFMDReconstructor.h"           // ALIFMDRECONSTRUCTOR_H
#include "AliFMDRawStream.h"               // ALIFMDRAWSTREAM_H
#include "AliFMDRawReader.h"               // ALIFMDRAWREADER_H
#include "AliFMDMultAlgorithm.h" 	   // ALIFMDMULTALGORITHM_H
#include "AliFMDMultPoisson.h"		   // ALIFMDMULTPOISSON_H
#include "AliFMDMultNaiive.h"		   // ALIFMDMULTNAIIVE_H

//____________________________________________________________________
ClassImp(AliFMDReconstructor)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliFMDReconstructor::AliFMDReconstructor()
  : AliReconstructor(),
    fPedestal(0),
    fPedestalWidth(0),
    fPedestalFactor(0)
{
  // Make a new FMD reconstructor object - default CTOR.
  AliFMDParameters* pars = AliFMDParameters::Instance();
  fPedestal       = pars->GetPedestal();
  fPedestalWidth  = pars->GetPedestalWidth();
  fPedestalFactor = pars->GetPedestalFactor();

  fAlgorithms.Add(new AliFMDMultNaiive);
  fAlgorithms.Add(new AliFMDMultPoisson);

  TIter next(&fAlgorithms);
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PreRun(0);
}

//____________________________________________________________________
AliFMDReconstructor::AliFMDReconstructor(const AliFMDReconstructor& other)
  : AliReconstructor(),
    fPedestal(0),
    fPedestalWidth(0),
    fPedestalFactor(0)
{
  // Copy constructor
  fPedestal       = other.fPedestal;
  fPedestalWidth  = other.fPedestalWidth;
  fPedestalFactor = other.fPedestalFactor;

  fAlgorithms.Delete();
  TIter next(&(other.fAlgorithms));
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    fAlgorithms.Add(algorithm);
  fAlgorithms.SetOwner(kFALSE);
}

//____________________________________________________________________
AliFMDReconstructor&
AliFMDReconstructor::operator=(const AliFMDReconstructor& other)
{
  // Assignment operator
  fPedestal       = other.fPedestal;
  fPedestalWidth  = other.fPedestalWidth;
  fPedestalFactor = other.fPedestalFactor;

  fAlgorithms.Delete();
  TIter next(&(other.fAlgorithms));
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    fAlgorithms.Add(algorithm);
  fAlgorithms.SetOwner(kFALSE);

  return *this;
}

//____________________________________________________________________
AliFMDReconstructor::~AliFMDReconstructor()
{
  // Destructor
  fAlgorithms.Delete();
}

//____________________________________________________________________
void
AliFMDReconstructor::Init(AliRunLoader* runLoader)
{
  // Initialize the reconstructor
  AliDebug(1, Form("Init called with runloader 0x%x", runLoader));
  fCurrentVertex = 0;
  if (!runLoader) {
    Warning("Init", "No run loader");
    return;
  }
  AliHeader* header = runLoader->GetHeader();
  if (!header) {
    Warning("Init", "No header");
    return;
  }
  AliGenEventHeader* eventHeader = header->GenEventHeader();
  if (!eventHeader) {
    Warning("Init", "no event header");
    return;
  }
  TArrayF vtx;
  eventHeader->PrimaryVertex(vtx);
  fCurrentVertex = vtx[2];
  AliDebug(1, Form("Primary vertex Z coordinate for event # %d/%d is %f",
		   header->GetRun(), header->GetEvent(), fCurrentVertex));
}

//____________________________________________________________________
void
AliFMDReconstructor::ConvertDigits(AliRawReader* reader,
				   TTree* digitsTree) const
{
  // Convert Raw digits to AliFMDDigit's in a tree
  AliFMDRawReader rawRead(reader, digitsTree);
  // rawRead.SetSampleRate(fFMD->GetSampleRate());
  rawRead.Exec();
}

//____________________________________________________________________
void
AliFMDReconstructor::Reconstruct(TTree* digitsTree,
				 TTree* clusterTree) const
{
  // Reconstruct event from digits in tree
  // Get the FMD branch holding the digits.
  // FIXME: The vertex may not be known yet, so we may have to move
  // some of this to FillESD.
  AliDebug(1, "Reconstructing from digits in a tree");

  TBranch *digitBranch = digitsTree->GetBranch("FMD");
  TClonesArray* digits = new TClonesArray("AliFMDDigit");
  if (!digitBranch) {
    Error("Exec", "No digit branch for the FMD found");
    return;
  }
  digitBranch->SetAddress(&digits);

  TIter next(&fAlgorithms);
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PreEvent(clusterTree, fCurrentVertex);
  digitBranch->GetEntry(0);

  ProcessDigits(digits);

  next.Reset();
  algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PostEvent();
  clusterTree->Fill();
}

//____________________________________________________________________
void
AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
{
  // For each digit, find the pseudo rapdity, azimuthal angle, and
  // number of corrected ADC counts, and pass it on to the algorithms
  // used.
  Int_t nDigits = digits->GetEntries();
  AliDebug(1, Form("Got %d digits", nDigits));
  for (Int_t i = 0; i < nDigits; i++) {
    AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
    AliFMDGeometry* fmd = AliFMDGeometry::Instance();
    AliFMDDetector* subDetector = fmd->GetDetector(digit->Detector());
    if (!subDetector) {
      Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
      continue;
    }

    AliFMDRing* ring  = subDetector->GetRing(digit->Ring());
    Float_t     ringZ = subDetector->GetRingZ(digit->Ring());
    if (!ring) {
      Warning("ProcessDigits", "Unknown ring: FMD%d%c", digit->Detector(),
	      digit->Ring());
      break;
    }

    Float_t  realZ    = fCurrentVertex + ringZ;
    Float_t  stripR   = ((ring->GetHighR() - ring->GetLowR())
			 / ring->GetNStrips() * (digit->Strip() + .5)
			 + ring->GetLowR());
    Float_t  theta    = TMath::ATan2(stripR, realZ);
    Float_t  phi      = (2 * TMath::Pi() / ring->GetNSectors()
			 * (digit->Sector() + .5));
    Float_t  eta      = -TMath::Log(TMath::Tan(theta / 2));
    UShort_t counts   = SubtractPedestal(digit);

    TIter next(&fAlgorithms);
    AliFMDMultAlgorithm* algorithm = 0;
    while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
      algorithm->ProcessDigit(digit, eta, phi, counts);
  }
}

//____________________________________________________________________
UShort_t
AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
{
  // Member function to subtract the pedestal from a digit
  // This implementation does nothing, but a derived class could over
  // load this to subtract a pedestal that was given in a database or
  // something like that.

  Int_t counts = 0;
  Float_t ped = fPedestal + fPedestalFactor * fPedestalWidth;
  if (digit->Count3() > 0)      counts = digit->Count3();
  else if (digit->Count2() > 0) counts = digit->Count2();
  else                          counts = digit->Count1();
  counts = TMath::Max(Int_t(counts - ped), 0);
  return  UShort_t(counts);
}

//____________________________________________________________________
void
AliFMDReconstructor::FillESD(TTree*  /* digitsTree */,
			     TTree*  /* clusterTree */,
			     AliESD* /* esd*/) const
{
  // nothing to be done
  // FIXME: The vertex may not be known when Reconstruct is executed,
  // so we may have to move some of that member function here.

}

//____________________________________________________________________
//
// EOF
//
<commit_msg>Removing memory leak<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//____________________________________________________________________
//
// This is a class that constructs AliFMDMult (reconstructed
// multiplicity) from of Digits
//
// This class reads either digits from a TClonesArray or raw data from
// a DDL file (or similar), and stores the read ADC counts in an
// internal cache (fAdcs).
//
// From the cached values it then calculates the number of particles
// that hit a region of the FMDs, as specified by the user.
//
// The reconstruction can be done in two ways: Either via counting the
// number of empty strips (Poisson method), or by converting the ADC
// signal to an energy deposition, and then dividing by the typical
// energy loss of a particle.
//
//      +---------------------+       +---------------------+
//      | AliFMDReconstructor |<>-----| AliFMDMultAlgorithm |
//      +---------------------+       +---------------------+
//                                               ^
//                                               |
//                                   +-----------+---------+
//                                   |                     |
//                         +-------------------+   +------------------+
//                         | AliFMDMultPoisson |   | AliFMDMultNaiive |
//                         +-------------------+   +------------------+
//
// AliFMDReconstructor acts as a manager class.  It contains a list of
// AliFMDMultAlgorithm objects.  The call graph looks something like
//
//
//       +----------------------+            +----------------------+
//       | :AliFMDReconstructor |            | :AliFMDMultAlgorithm |
//       +----------------------+            +----------------------+
//                  |                                  |
//    Reconstruct  +-+                                 |
//    ------------>| |                         PreRun +-+
//                 | |------------------------------->| |
//                 | |                                +-+
//                 | |-----+ (for each event)          |
//                 | |     | *ProcessEvent             |
//                 |+-+    |                           |
//                 || |<---+                 PreEvent +-+
//                 || |------------------------------>| |
//                 || |                               +-+
//                 || |-----+                          |
//                 || |     | ProcessDigits            |
//                 ||+-+    |                          |
//                 ||| |<---+                          |
//                 ||| |         *ProcessDigit(digit) +-+
//                 ||| |----------------------------->| |
//                 ||| |                              +-+
//                 ||+-+                               |
//                 || |                     PostEvent +-+
//                 || |------------------------------>| |
//                 || |                               +-+
//                 |+-+                                |
//                 | |                        PostRun +-+
//                 | |------------------------------->| |
//                 | |                                +-+
//                 +-+                                 |
//                  |                                  |
//
//
//
//-- Authors: Evgeny Karpechev(INR) and Alla Maevsksia
//  Latest changes by Christian Holm Christensen <cholm@nbi.dk>
//
//
//____________________________________________________________________

#include <AliLog.h>                        // ALILOG_H
#include <AliRun.h>                        // ALIRUN_H
#include <AliRunLoader.h>                  // ALIRUNLOADER_H
#include <AliLoader.h>                     // ALILOADER_H
#include <AliHeader.h>                     // ALIHEADER_H
#include <AliRawReader.h>                  // ALIRAWREADER_H
#include <AliGenEventHeader.h>             // ALIGENEVENTHEADER_H
#include "AliFMD.h"         		   // ALIFMD_H
#include "AliFMDGeometry.h"                // ALIFMDGEOMETRY_H
#include "AliFMDParameters.h"              // ALIFMDPARAMETERS_H
#include "AliFMDDetector.h"                // ALIFMDDETECTOR_H
#include "AliFMDRing.h"                    // ALIFMDRING_H
#include "AliFMDDigit.h"                   // ALIFMDDIGIT_H
#include "AliFMDReconstructor.h"           // ALIFMDRECONSTRUCTOR_H
#include "AliFMDRawStream.h"               // ALIFMDRAWSTREAM_H
#include "AliFMDRawReader.h"               // ALIFMDRAWREADER_H
#include "AliFMDMultAlgorithm.h" 	   // ALIFMDMULTALGORITHM_H
#include "AliFMDMultPoisson.h"		   // ALIFMDMULTPOISSON_H
#include "AliFMDMultNaiive.h"		   // ALIFMDMULTNAIIVE_H

//____________________________________________________________________
ClassImp(AliFMDReconstructor)
#if 0
  ; // This is here to keep Emacs for indenting the next line
#endif

//____________________________________________________________________
AliFMDReconstructor::AliFMDReconstructor()
  : AliReconstructor(),
    fPedestal(0),
    fPedestalWidth(0),
    fPedestalFactor(0)
{
  // Make a new FMD reconstructor object - default CTOR.
  AliFMDParameters* pars = AliFMDParameters::Instance();
  fPedestal       = pars->GetPedestal();
  fPedestalWidth  = pars->GetPedestalWidth();
  fPedestalFactor = pars->GetPedestalFactor();

  fAlgorithms.Add(new AliFMDMultNaiive);
  fAlgorithms.Add(new AliFMDMultPoisson);

  TIter next(&fAlgorithms);
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PreRun(0);
}

//____________________________________________________________________
AliFMDReconstructor::AliFMDReconstructor(const AliFMDReconstructor& other)
  : AliReconstructor(),
    fPedestal(0),
    fPedestalWidth(0),
    fPedestalFactor(0)
{
  // Copy constructor
  fPedestal       = other.fPedestal;
  fPedestalWidth  = other.fPedestalWidth;
  fPedestalFactor = other.fPedestalFactor;

  fAlgorithms.Delete();
  TIter next(&(other.fAlgorithms));
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    fAlgorithms.Add(algorithm);
  fAlgorithms.SetOwner(kFALSE);
}

//____________________________________________________________________
AliFMDReconstructor&
AliFMDReconstructor::operator=(const AliFMDReconstructor& other)
{
  // Assignment operator
  fPedestal       = other.fPedestal;
  fPedestalWidth  = other.fPedestalWidth;
  fPedestalFactor = other.fPedestalFactor;

  fAlgorithms.Delete();
  TIter next(&(other.fAlgorithms));
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    fAlgorithms.Add(algorithm);
  fAlgorithms.SetOwner(kFALSE);

  return *this;
}

//____________________________________________________________________
AliFMDReconstructor::~AliFMDReconstructor()
{
  // Destructor
  fAlgorithms.Delete();
}

//____________________________________________________________________
void
AliFMDReconstructor::Init(AliRunLoader* runLoader)
{
  // Initialize the reconstructor
  AliDebug(1, Form("Init called with runloader 0x%x", runLoader));
  fCurrentVertex = 0;
  if (!runLoader) {
    Warning("Init", "No run loader");
    return;
  }
  AliHeader* header = runLoader->GetHeader();
  if (!header) {
    Warning("Init", "No header");
    return;
  }
  AliGenEventHeader* eventHeader = header->GenEventHeader();
  if (!eventHeader) {
    Warning("Init", "no event header");
    return;
  }
  TArrayF vtx;
  eventHeader->PrimaryVertex(vtx);
  fCurrentVertex = vtx[2];
  AliDebug(1, Form("Primary vertex Z coordinate for event # %d/%d is %f",
		   header->GetRun(), header->GetEvent(), fCurrentVertex));
}

//____________________________________________________________________
void
AliFMDReconstructor::ConvertDigits(AliRawReader* reader,
				   TTree* digitsTree) const
{
  // Convert Raw digits to AliFMDDigit's in a tree
  AliFMDRawReader rawRead(reader, digitsTree);
  // rawRead.SetSampleRate(fFMD->GetSampleRate());
  rawRead.Exec();
}

//____________________________________________________________________
void
AliFMDReconstructor::Reconstruct(TTree* digitsTree,
				 TTree* clusterTree) const
{
  // Reconstruct event from digits in tree
  // Get the FMD branch holding the digits.
  // FIXME: The vertex may not be known yet, so we may have to move
  // some of this to FillESD.
  AliDebug(1, "Reconstructing from digits in a tree");

  TBranch *digitBranch = digitsTree->GetBranch("FMD");
  if (!digitBranch) {
    Error("Exec", "No digit branch for the FMD found");
    return;
  }
  TClonesArray* digits = new TClonesArray("AliFMDDigit");
  digitBranch->SetAddress(&digits);

  TIter next(&fAlgorithms);
  AliFMDMultAlgorithm* algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PreEvent(clusterTree, fCurrentVertex);
  digitBranch->GetEntry(0);

  ProcessDigits(digits);

  next.Reset();
  algorithm = 0;
  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
    algorithm->PostEvent();
  clusterTree->Fill();
  digits->Delete();
  delete digits;
}

//____________________________________________________________________
void
AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
{
  // For each digit, find the pseudo rapdity, azimuthal angle, and
  // number of corrected ADC counts, and pass it on to the algorithms
  // used.
  Int_t nDigits = digits->GetEntries();
  AliDebug(1, Form("Got %d digits", nDigits));
  for (Int_t i = 0; i < nDigits; i++) {
    AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
    AliFMDGeometry* fmd = AliFMDGeometry::Instance();
    AliFMDDetector* subDetector = fmd->GetDetector(digit->Detector());
    if (!subDetector) {
      Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
      continue;
    }

    AliFMDRing* ring  = subDetector->GetRing(digit->Ring());
    Float_t     ringZ = subDetector->GetRingZ(digit->Ring());
    if (!ring) {
      Warning("ProcessDigits", "Unknown ring: FMD%d%c", digit->Detector(),
	      digit->Ring());
      break;
    }

    Float_t  realZ    = fCurrentVertex + ringZ;
    Float_t  stripR   = ((ring->GetHighR() - ring->GetLowR())
			 / ring->GetNStrips() * (digit->Strip() + .5)
			 + ring->GetLowR());
    Float_t  theta    = TMath::ATan2(stripR, realZ);
    Float_t  phi      = (2 * TMath::Pi() / ring->GetNSectors()
			 * (digit->Sector() + .5));
    Float_t  eta      = -TMath::Log(TMath::Tan(theta / 2));
    UShort_t counts   = SubtractPedestal(digit);

    TIter next(&fAlgorithms);
    AliFMDMultAlgorithm* algorithm = 0;
    while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
      algorithm->ProcessDigit(digit, eta, phi, counts);
  }
}

//____________________________________________________________________
UShort_t
AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
{
  // Member function to subtract the pedestal from a digit
  // This implementation does nothing, but a derived class could over
  // load this to subtract a pedestal that was given in a database or
  // something like that.

  Int_t counts = 0;
  Float_t ped = fPedestal + fPedestalFactor * fPedestalWidth;
  if (digit->Count3() > 0)      counts = digit->Count3();
  else if (digit->Count2() > 0) counts = digit->Count2();
  else                          counts = digit->Count1();
  counts = TMath::Max(Int_t(counts - ped), 0);
  return  UShort_t(counts);
}

//____________________________________________________________________
void
AliFMDReconstructor::FillESD(TTree*  /* digitsTree */,
			     TTree*  /* clusterTree */,
			     AliESD* /* esd*/) const
{
  // nothing to be done
  // FIXME: The vertex may not be known when Reconstruct is executed,
  // so we may have to move some of that member function here.

}

//____________________________________________________________________
//
// EOF
//
<|endoftext|>


<commit_before>
#ifndef MANAGER_HPP_
#define MANAGER_HPP_

#include <iostream>

#include <vector>			 // vector
#include <random>            // mt19937, uniform_int_distribution, random_device

#include <utility>			 // make_pair

#include <boost/thread/thread.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/atomic.hpp>

#include "Chromosome.hpp"
#include "RouletteWheel.hpp"
#include "Result.hpp"

#include "SafeQueue.hpp"

template <class T>
class Manager {
protected:

	unsigned int population_size;
	unsigned int chromosome_size;

	unsigned int max_generation_number;

	T max_chromosome_value;
	T min_chromosome_value;

	bool use_self_adaptive;
	double mutation_rate;
	double mutation_change_rate;
	double similarity_index;

	double crossover_rate;

	std::vector<Chromosome<T> > population;

	// Need to have some way of ensure no duplication of solutions
	std::vector<Chromosome<T> > solutions;

	RouletteWheel rw;

	//SafeQueue<unsigned int> safe_queue;
	SafeQueue<Result > result_queue;

	boost::thread_group fitness_group;

	std::mt19937 rand_engine;
	std::uniform_real_distribution<float> op_dist;
	std::uniform_real_distribution<float> mutation_dist;
	//std::uniform_int_distribution<int> chrom_dist;

	// With this we can limit the number of threads used
	unsigned int num_threads_used;
	unsigned int max_num_threads;

	// Library flags
	//int number_of_threads = 5;
	boost::atomic<bool> done;
	boost::atomic<bool> waiting;

	boost::condition_variable m_cond;
	boost::mutex mtx_;

	// Fitness function
	double (*fitness_function)(Chromosome<T>);

public:

    // TODO this should take a configuration struct/object that has a lot of default parameters
	/**
	 * Create a manager for GA.
	 * @param population_size The size of population.
	 * @param chromosome_size The size of each chromosome.
	 * @param max_chromosome_value The maximum possible value for the chromosome.
	 * @param min_chromosome_value The minimum possible value for the chromosome.
	 * @param use_self_adaptive Whether to use a self adaptive approach. If this is true
	 * then the mutation rate will be updated based on the similarity of the population.
	 * @param mutation_rate The mutation rate that is used. This is the likelihood that the
	 * mutation operation is applied. If the self adaptive approach is used then this is
	 * the initial mutation rate.
	 * @param mutation_change_rate The rate by which the mutation rate will be updated.
	 * If use_self_adaptive is set to false then this parameter is ignored.
	 * @param similarity_index The threshold at which the similarity mutation rate is
	 * updated.
	 * @param crossover_rate The crossover rate, the likelihood that a chromosome
	 * has the crossover operation applied to it.
	 * @param cloning_rate The cloning rate, the likelihood that a cromosome will be
	 * cloned into the new population.
	 */
	Manager(unsigned int population_size, unsigned int chromosome_size, unsigned int max_generation_number,
			T max_chromosome_value, T min_chromosome_value, bool use_self_adaptive,
			double mutation_rate, double mutation_change_rate, double similarity_index,
			double crossover_rate, unsigned int num_threads) : population_size(population_size),
			chromosome_size(chromosome_size), max_generation_number(max_generation_number),
			max_chromosome_value(max_chromosome_value), min_chromosome_value(min_chromosome_value),
			use_self_adaptive(use_self_adaptive), mutation_rate(mutation_rate),
			mutation_change_rate(mutation_change_rate), similarity_index(similarity_index),
			crossover_rate(crossover_rate), max_num_threads(num_threads)//, safe_queue(population_size),
			//result_queue(population_size)
			{
		population = std::vector<Chromosome<T > >(population_size);
		initialize();
	}

    // TODO this should take a configuration struct/object that has a lot of default parameters
	/**
	 * Create a non self-adaptive GA manager
	 * @param population_size The size of population.
	 * @param chromosome_size The size of each chromosome.
	 * @param max_chromosome_value The maximum possible value for the chromosome.
	 * @param min_chromosome_value The minimum possible value for the chromosome.
	 * @param mutation_rate The mutation rate that is used. This is the likelihood that the
	 * mutation operation is applied. If the self adaptive approach is used then this is
	 * the initial mutation rate.
	 * @param crossover_rate The crossover rate, the likelihood that a chromosome
	 * has the crossover operation applied to it.
	 * @param cloning_rate The cloning rate, the likelihood that a cromosome will be
	 * cloned into the new population.
	 */
	Manager(unsigned int population_size, unsigned int chromosome_size, unsigned int max_generation_number,
				T max_chromosome_value, T min_chromosome_value, double mutation_rate,
				double crossover_rate, unsigned int num_threads) : population_size(population_size),
				chromosome_size(chromosome_size), max_generation_number(max_generation_number),
				max_chromosome_value(max_chromosome_value), min_chromosome_value(min_chromosome_value),
				use_self_adaptive(false), mutation_rate(mutation_rate), mutation_change_rate(0),
				similarity_index(0), crossover_rate(crossover_rate), population(population_size),
				max_num_threads(num_threads){

		initialize();

	}

	~Manager() {

	}

    /**
	 * Run the algorithm for the specificed number of generations
	 */
	void run(double (*fitness_function)(Chromosome<T>)) {
		this->fitness_function = fitness_function;

		initPopulation();

		for(unsigned int i = 0; i < max_generation_number; i++) {
			//std::cout << "Generation " << i << std::endl;
			runGeneration();
		}

		done = true;
		m_cond.notify_all();

		//TODO remove
		//safe_queue.finish();
		//result_queue.finish();

		fitness_group.join_all();

	}

	/**
	 * Get another chromosome and apply the fitness function.
	 * @param param The manager the thread is running for.
	 */
	static void calcFitnessFunction(void *param, unsigned int start_index, unsigned int problem_size) {
		if(param != NULL) {
			Manager * m = (Manager *) param;
			unsigned int problem_index;

			std::vector<Result > results;
			while(!m->done) {

				if(m->wait_for_work()) {
					break;
				}

				// Can we trust the user to not change the chromosome? No.
				for(unsigned int i = 0; i < problem_size; i++) {

					Chromosome<T> t = m->population[start_index+i];

					results.push_back(Result(start_index+i, m->fitness_function(t)));
				}

				// Store them in results
				m->result_queue.push(results);

				results.clear();

				//TODO consider a barrier to make all the threads wait until all other threads are complete and then apply breeding in the threads.
			}
		}
	}

    // TODO make this private (after testing)
	/**
	 * Create an initial population of random chromosomes.
	 */
	void initPopulation() {
		Chromosome<unsigned int>::initPopulation(this->population, this->population_size, this->chromosome_size);
	}

    /**
	 * Returns the population size specified for the manager class.
     * @return The population size
     */
	unsigned int size() {
		return this->population_size;
	}

    /**
     * Returns the entire chromosome population.
     * @return The chromosome population
     */
	std::vector<Chromosome<T> > getPopulation() {
		return this->population;
	}

private:

	bool wait_for_work() {
		boost::unique_lock<boost::mutex> lock(mtx_);
		if(!done) {
			if(!waiting) {
				m_cond.wait(lock);
			}
		}
		else {
			return true;
		}
		return false;
	}

	void set_waiting(bool val){
		boost::unique_lock<boost::mutex> guard(mtx_);
		waiting = val;
	}

	/**
	 * Setup the necessary variables for genetic algorithm.
	 */
	void initialize() {
		// Create the random objects that will be used
		std::random_device rd;
		rand_engine = std::mt19937(rd());
		op_dist = std::uniform_real_distribution<float>(0.0, 1.0);
		mutation_dist = std::uniform_real_distribution<float>(0.0, 1.0);
		Chromosome<T>::initialize(chromosome_size, min_chromosome_value, max_chromosome_value);
		done = false;

		int problem_size = population_size/max_num_threads;
		int count = 0;

		// Create the number of threads requested. If we are using self adaptive we will require 1 thread for the self adaptive
		for(unsigned int i = 0; i < max_num_threads; i++) {

			if (i+1 == max_num_threads && population_size % max_num_threads != 0) {

				// Handle the case where the problem_size does not evenly divide by the
				// number of threads available. Last thread receives remainder.
				// This is not the best solution but is passible.
				problem_size = population_size % max_num_threads;
			}

			//pthread_create(&threadpool.back(), 0, calcFitnessFunction, (void *) this);
			fitness_group.create_thread(boost::bind(calcFitnessFunction, (void *) this, count, problem_size));
			count+= problem_size;
		}
	}

	/**
	 * Mutate the given chromosome on the likelihood of the mutation rate.
	 * @param chromosome The chromosome to mutate.
	 */
	void mutate(Chromosome<T > &chromosome) {
		if(mutation_dist(rand_engine) <= mutation_rate) {
			chromosome.mutate();
		}
	}

	/**
	 * Apply the fitness function to the population. Given the result of the
	 * fitness function, the next population is bred.
	 */
	void runGeneration() {

		set_waiting(true);
		m_cond.notify_all();

		// Main thread will wait for all children to finish executing before proceeding.
		// Construct the list of results for the fitness function in a map which maps the chromosome's index to the chromosome's fitness value.
		std::vector<Result >fitness_results;

		// Wait for all the chromosomes to finish calculating their fitness value.
		std::vector<Result > results;
		while(fitness_results.size() < population_size) {
			while(result_queue.popAll(results, false)) {

				for(unsigned int i = 0; i < results.size(); i++) {
					fitness_results.push_back(results[i]);
				}
				results.clear();
				//TODO add results to solutions.
			}
		}

		set_waiting(false);

		breed(fitness_results);
	}

	/**
	 * Prepare the population for the next generation by apply the genetic operations.
	 */
	void breed(std::vector<Result > &fitness) {
		std::vector<Chromosome<T> > new_population;

		//std::cout << "Breeding" << std::endl;
		rw.init(fitness);

		// Iterate through the chromosomes
		while(new_population.size() < population_size) {
			// Use a random number between to identify which operation to apply (each operation gets a slice of the range)
			float selected_operation = op_dist(rand_engine);
			unsigned int selected_chromosome = rw.next();

			if(selected_operation <= crossover_rate) {
				// Crossover
				unsigned int other_selected_chromosome = rw.next();

				// If the chromosome selected are the same than there is no point apply the crossover.
				if(other_selected_chromosome != selected_chromosome) {
					population[selected_chromosome].crossover(population[other_selected_chromosome], new_population);
				} else {
					population[selected_chromosome].cloning(new_population);
					population[other_selected_chromosome].cloning(new_population);
				}

				// Mutate the second chromosome in the crossover
				mutate((*(new_population.end() - 2)));

				// Handle the case where the new_population.size() -1 == popluation size and then crossover is selected.
				if(new_population.size() == population_size+1) {
					new_population.pop_back();
				}
			}
			else {
				// Clone
                population[selected_chromosome].cloning(new_population);
			}

			// Mutate the chromosome
			mutate(new_population.back());

		}

		//std::cout << "Finished Breeding" << std::endl;

		// Update the population to the new population
		population = new_population;
	}
};

#endif /* MANAGER_HPP_ */
<commit_msg>ADDED: solutions storage.<commit_after>
#ifndef MANAGER_HPP_
#define MANAGER_HPP_

#include <iostream>

#include <vector>			 // vector
#include <random>            // mt19937, uniform_int_distribution, random_device

#include <utility>			 // make_pair

#include <boost/thread/thread.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/atomic.hpp>

#include "Chromosome.hpp"
#include "RouletteWheel.hpp"
#include "Result.hpp"

#include "SafeQueue.hpp"

template <class T>
class Manager {
protected:

	unsigned int population_size;
	unsigned int chromosome_size;

	unsigned int max_generation_number;

	T max_chromosome_value;
	T min_chromosome_value;

	bool use_self_adaptive;
	double mutation_rate;
	double mutation_change_rate;
	double similarity_index;

	double crossover_rate;

	std::vector<Chromosome<T> > population;

	// Need to have some way of ensure no duplication of solutions
	std::vector<Chromosome<T> > solutions;

	RouletteWheel rw;

	//SafeQueue<unsigned int> safe_queue;
	SafeQueue<Result > result_queue;

	boost::thread_group fitness_group;

	std::mt19937 rand_engine;
	std::uniform_real_distribution<float> op_dist;
	std::uniform_real_distribution<float> mutation_dist;
	//std::uniform_int_distribution<int> chrom_dist;

	// With this we can limit the number of threads used
	unsigned int num_threads_used;
	unsigned int max_num_threads;

	// Library flags
	//int number_of_threads = 5;
	boost::atomic<bool> done;
	boost::atomic<bool> waiting;

	boost::condition_variable m_cond;
	boost::mutex mtx_;

	// Fitness function
	double (*fitness_function)(Chromosome<T>);

public:

    // TODO this should take a configuration struct/object that has a lot of default parameters
	/**
	 * Create a manager for GA.
	 * @param population_size The size of population.
	 * @param chromosome_size The size of each chromosome.
	 * @param max_chromosome_value The maximum possible value for the chromosome.
	 * @param min_chromosome_value The minimum possible value for the chromosome.
	 * @param use_self_adaptive Whether to use a self adaptive approach. If this is true
	 * then the mutation rate will be updated based on the similarity of the population.
	 * @param mutation_rate The mutation rate that is used. This is the likelihood that the
	 * mutation operation is applied. If the self adaptive approach is used then this is
	 * the initial mutation rate.
	 * @param mutation_change_rate The rate by which the mutation rate will be updated.
	 * If use_self_adaptive is set to false then this parameter is ignored.
	 * @param similarity_index The threshold at which the similarity mutation rate is
	 * updated.
	 * @param crossover_rate The crossover rate, the likelihood that a chromosome
	 * has the crossover operation applied to it.
	 * @param cloning_rate The cloning rate, the likelihood that a cromosome will be
	 * cloned into the new population.
	 */
	Manager(unsigned int population_size, unsigned int chromosome_size, unsigned int max_generation_number,
			T max_chromosome_value, T min_chromosome_value, bool use_self_adaptive,
			double mutation_rate, double mutation_change_rate, double similarity_index,
			double crossover_rate, unsigned int num_threads) : population_size(population_size),
			chromosome_size(chromosome_size), max_generation_number(max_generation_number),
			max_chromosome_value(max_chromosome_value), min_chromosome_value(min_chromosome_value),
			use_self_adaptive(use_self_adaptive), mutation_rate(mutation_rate),
			mutation_change_rate(mutation_change_rate), similarity_index(similarity_index),
			crossover_rate(crossover_rate), max_num_threads(num_threads)//, safe_queue(population_size),
			//result_queue(population_size)
			{
		population = std::vector<Chromosome<T > >(population_size);
		initialize();
	}

    // TODO this should take a configuration struct/object that has a lot of default parameters
	/**
	 * Create a non self-adaptive GA manager
	 * @param population_size The size of population.
	 * @param chromosome_size The size of each chromosome.
	 * @param max_chromosome_value The maximum possible value for the chromosome.
	 * @param min_chromosome_value The minimum possible value for the chromosome.
	 * @param mutation_rate The mutation rate that is used. This is the likelihood that the
	 * mutation operation is applied. If the self adaptive approach is used then this is
	 * the initial mutation rate.
	 * @param crossover_rate The crossover rate, the likelihood that a chromosome
	 * has the crossover operation applied to it.
	 * @param cloning_rate The cloning rate, the likelihood that a cromosome will be
	 * cloned into the new population.
	 */
	Manager(unsigned int population_size, unsigned int chromosome_size, unsigned int max_generation_number,
				T max_chromosome_value, T min_chromosome_value, double mutation_rate,
				double crossover_rate, unsigned int num_threads) : population_size(population_size),
				chromosome_size(chromosome_size), max_generation_number(max_generation_number),
				max_chromosome_value(max_chromosome_value), min_chromosome_value(min_chromosome_value),
				use_self_adaptive(false), mutation_rate(mutation_rate), mutation_change_rate(0),
				similarity_index(0), crossover_rate(crossover_rate), population(population_size),
				max_num_threads(num_threads){

		initialize();

	}

	~Manager() {

	}

    /**
	 * Run the algorithm for the specificed number of generations
	 */
	void run(double (*fitness_function)(Chromosome<T>)) {
		this->fitness_function = fitness_function;

		initPopulation();

		for(unsigned int i = 0; i < max_generation_number; i++) {
			//std::cout << "Generation " << i << std::endl;
			runGeneration();
		}

		done = true;
		m_cond.notify_all();

		fitness_group.join_all();

	}

	/**
	 * Get another chromosome and apply the fitness function.
	 * @param param The manager the thread is running for.
	 */
	static void calcFitnessFunction(Manager *m, unsigned int start_index, unsigned int problem_size) {

		unsigned int problem_index;

		std::vector<Result > results;
		while(!m->done) {

			if(m->wait_for_work()) {
				break;
			}

			// Can we trust the user to not change the chromosome? No.
			for(unsigned int i = 0; i < problem_size; i++) {

				Chromosome<T> t = m->population[start_index+i];

				results.push_back(Result(start_index+i, m->fitness_function(t)));
			}

			// Store them in results
			m->result_queue.push(results);

			results.clear();

			//TODO consider a barrier to make all the threads wait until all other threads are complete and then apply breeding in the threads.
		}
	}

	std::vector<Chromosome<T > > getSolutions() {
		return this->solutions;
	}

    // TODO make this private (after testing)
	/**
	 * Create an initial population of random chromosomes.
	 */
	void initPopulation() {
		Chromosome<unsigned int>::initPopulation(this->population, this->population_size, this->chromosome_size);
	}

    /**
	 * Returns the population size specified for the manager class.
     * @return The population size
     */
	unsigned int size() {
		return this->population_size;
	}

    /**
     * Returns the entire chromosome population.
     * @return The chromosome population
     */
	std::vector<Chromosome<T> > getPopulation() {
		return this->population;
	}

private:

	bool wait_for_work() {
		boost::unique_lock<boost::mutex> lock(mtx_);
		if(!done) {
			if(!waiting) {
				m_cond.wait(lock);
			}
		}
		else {
			return true;
		}
		return false;
	}

	void set_waiting(bool val){
		boost::unique_lock<boost::mutex> guard(mtx_);
		waiting = val;
	}

	/**
	 * Setup the necessary variables for genetic algorithm.
	 */
	void initialize() {
		// Create the random objects that will be used
		std::random_device rd;
		rand_engine = std::mt19937(rd());
		op_dist = std::uniform_real_distribution<float>(0.0, 1.0);
		mutation_dist = std::uniform_real_distribution<float>(0.0, 1.0);
		Chromosome<T>::initialize(chromosome_size, min_chromosome_value, max_chromosome_value);
		done = false;

		int problem_size = population_size/max_num_threads;
		int count = 0;

		// Create the number of threads requested. If we are using self adaptive we will require 1 thread for the self adaptive
		for(unsigned int i = 0; i < max_num_threads; i++) {

			if (i+1 == max_num_threads && population_size % max_num_threads != 0) {

				// Handle the case where the problem_size does not evenly divide by the
				// number of threads available. Last thread receives remainder.
				// This is not the best solution but is passible.
				problem_size = population_size % max_num_threads;
			}

			//pthread_create(&threadpool.back(), 0, calcFitnessFunction, (void *) this);
			fitness_group.create_thread(boost::bind(calcFitnessFunction, this, count, problem_size));
			count+= problem_size;
		}
	}

	/**
	 * Mutate the given chromosome on the likelihood of the mutation rate.
	 * @param chromosome The chromosome to mutate.
	 */
	void mutate(Chromosome<T > &chromosome) {
		if(mutation_dist(rand_engine) <= mutation_rate) {
			chromosome.mutate();
		}
	}

	/**
	 * Apply the fitness function to the population. Given the result of the
	 * fitness function, the next population is bred.
	 */
	void runGeneration() {

		set_waiting(true);
		m_cond.notify_all();

		// Main thread will wait for all children to finish executing before proceeding.
		// Construct the list of results for the fitness function in a map which maps the chromosome's index to the chromosome's fitness value.
		std::vector<Result >fitness_results;

		// Wait for all the chromosomes to finish calculating their fitness value.
		std::vector<Result > results;
		while(fitness_results.size() < population_size) {
			while(result_queue.popAll(results, false)) {

				for(unsigned int i = 0; i < results.size(); i++) {
					fitness_results.push_back(results[i]);

					//TODO add results to solutions.
					if(results[i].getResult() == 1.0) {
						solutions.push_back(population[results[i].getIndex()]);
					}
				}
				results.clear();

			}
		}

		set_waiting(false);

		breed(fitness_results);
	}

	/**
	 * Prepare the population for the next generation by apply the genetic operations.
	 */
	void breed(std::vector<Result > &fitness) {
		std::vector<Chromosome<T> > new_population;

		//std::cout << "Breeding" << std::endl;
		rw.init(fitness);

		// Iterate through the chromosomes
		while(new_population.size() < population_size) {
			// Use a random number between to identify which operation to apply (each operation gets a slice of the range)
			float selected_operation = op_dist(rand_engine);
			unsigned int selected_chromosome = rw.next();

			if(selected_operation <= crossover_rate) {
				// Crossover
				unsigned int other_selected_chromosome = rw.next();

				// If the chromosome selected are the same than there is no point apply the crossover.
				if(other_selected_chromosome != selected_chromosome) {
					population[selected_chromosome].crossover(population[other_selected_chromosome], new_population);
				} else {
					population[selected_chromosome].cloning(new_population);
					population[other_selected_chromosome].cloning(new_population);
				}

				// Mutate the second chromosome in the crossover
				mutate((*(new_population.end() - 2)));

				// Handle the case where the new_population.size() -1 == popluation size and then crossover is selected.
				if(new_population.size() == population_size+1) {
					new_population.pop_back();
				}
			}
			else {
				// Clone
                population[selected_chromosome].cloning(new_population);
			}

			// Mutate the chromosome
			mutate(new_population.back());

		}

		//std::cout << "Finished Breeding" << std::endl;

		// Update the population to the new population
		population = new_population;
	}
};

#endif /* MANAGER_HPP_ */
<|endoftext|>


<commit_before>#pragma once

#include <tinyfx.h>
#include <string>
#include <vector>

namespace tfx {
	struct VertexFormat {
		tfx_vertex_format fmt;
		VertexFormat() {
			this->fmt = tfx_vertex_format_start();
		}
		inline void add(size_t count, bool normalized = false, tfx_component_type type = TFX_TYPE_FLOAT) {
			tfx_vertex_format_add(&this->fmt, count, normalized, type);
		}
		inline void end() {
			tfx_vertex_format_end(&this->fmt);
		}
	};

	template <typename T>
	struct Buffer {
		tfx_buffer buffer;
		// Buffer(std::vector<T> &data, VertexFormat fmt, tfx_buffer_usage usage = TFX_USAGE_STATIC) {
		// 	this->buffer = tfx_buffer_new(&data[0], data.size()*sizeof(T), &fmt.fmt, usage);
		// }
		Buffer(tfx_buffer &buf) {
			this->buffer = buf;
		}
	};

	template <typename T>
	struct TransientBuffer {
		tfx_transient_buffer tvb;
		TransientBuffer(VertexFormat &fmt, uint16_t num) {
			tvb = tfx_transient_buffer_new(&fmt.fmt, num);
		}
	};

	struct Uniform {
		tfx_uniform uniform;
		Uniform(std::string name, tfx_uniform_type type, int count = 1) {
			this->uniform = tfx_uniform_new(name.c_str(), type, count);
		}
	};

	struct Canvas {
		tfx_canvas canvas;
		Canvas(uint16_t w, uint16_t h, tfx_format format = TFX_FORMAT_RGBA8_D16) {
			this->canvas = tfx_canvas_new(w, h, format);
		}
	};

	struct View {
		uint8_t id;
		View(uint8_t _id) {
			this->id = _id;
		}
		inline void set_canvas(Canvas *canvas) {
			tfx_view_set_canvas(this->id, &canvas->canvas);
		}
		inline void set_clear_color(int color = 0x000000ff) {
			tfx_view_set_clear_color(this->id, color);
		}
		inline void set_clear_depth(float depth = 1.0f) {
			tfx_view_set_clear_depth(this->id, depth);
		}
		inline void set_depth_test(tfx_depth_test mode = TFX_DEPTH_TEST_NONE) {
			tfx_view_set_depth_test(this->id, mode);
		}
		inline void set_scissor(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
			tfx_view_set_scissor(this->id, x, y, w, h);
		}
		inline uint16_t get_width() {
			return tfx_view_get_width(this->id);
		}
		inline uint16_t get_height() {
			return tfx_view_get_width(this->id);
		}
		inline void get_dimensions(uint16_t *w, uint16_t *h) {
			tfx_view_get_dimensions(this->id, w, h);
		}
		inline void touch() {
			tfx_touch(this->id);
		}
	};

	struct Texture {
		tfx_texture texture;
		Texture(uint16_t w, uint16_t h, void *data = NULL, bool gen_mips = true, tfx_format format = TFX_FORMAT_RGBA8, uint16_t flags = TFX_TEXTURE_FILTER_LINEAR) {
			this->texture = tfx_texture_new(w, h, data, gen_mips, format, flags);
		}
	};

	struct Program {
		tfx_program program;
		Program(std::string vss, std::string fss, const char *attribs[]) {
			this->program = tfx_program_new(vss.c_str(), fss.c_str(), attribs);
		}
	};

	inline void dump_caps() {
		tfx_dump_caps();
	}
	inline tfx_caps get_caps() {
		return tfx_get_caps();
	}
	inline void touch(uint8_t id) {
		tfx_touch(id);
	}
	inline void reset(uint16_t width, uint16_t height) {
		tfx_reset(width, height);
	}
	inline void shutdown() {
		tfx_shutdown();
	}
	inline tfx_stats frame() {
		return tfx_frame();
	}
	inline void set_uniform(Uniform &uniform, float data) {
		float tmp = data;
		tfx_set_uniform(&uniform.uniform, &tmp);
	}
	inline void set_uniform(Uniform &uniform, float *data) {
		tfx_set_uniform(&uniform.uniform, data);
	}
	inline void set_texture(Uniform &uniform, Texture &texture, uint8_t slot) {
		tfx_set_texture(&uniform.uniform, &texture.texture, slot);
	}
	inline void set_callback(tfx_draw_callback cb) {
		tfx_set_callback(cb);
	}
	inline void set_state(uint64_t flags) {
		tfx_set_state(flags);
	}
	template <typename T>
	inline void set_transient_buffer(TransientBuffer<T> tvb) {
		tfx_set_transient_buffer(tvb.tvb);
	}
	template <typename T>
	inline void set_vertices(Buffer<T> &vbo, int count = 0) {
		tfx_set_vertices(&vbo.buffer, count);
	}
	template <typename T>
	inline void set_indices(Buffer<T> &ibo, int count) {
		tfx_set_indices(&ibo.buffer, count);
	}
	inline void submit(View &view, Program &program, bool retain = false) {
		tfx_submit(view.id, program.program, retain);
	}
	// inline void blit(tfx_view *src, tfx_view *dst, uint16_t x, uint16_t y, uint16_t w, uint16_t h);

} // tfx
<commit_msg>allow using numeric view id for submit in c++ api<commit_after>#pragma once

#include <tinyfx.h>
#include <string>
#include <vector>

namespace tfx {
	struct VertexFormat {
		tfx_vertex_format fmt;
		VertexFormat() {
			this->fmt = tfx_vertex_format_start();
		}
		inline void add(size_t count, bool normalized = false, tfx_component_type type = TFX_TYPE_FLOAT) {
			tfx_vertex_format_add(&this->fmt, count, normalized, type);
		}
		inline void end() {
			tfx_vertex_format_end(&this->fmt);
		}
	};

	template <typename T>
	struct Buffer {
		tfx_buffer buffer;
		// Buffer(std::vector<T> &data, VertexFormat fmt, tfx_buffer_usage usage = TFX_USAGE_STATIC) {
		// 	this->buffer = tfx_buffer_new(&data[0], data.size()*sizeof(T), &fmt.fmt, usage);
		// }
		Buffer(tfx_buffer &buf) {
			this->buffer = buf;
		}
	};

	template <typename T>
	struct TransientBuffer {
		tfx_transient_buffer tvb;
		TransientBuffer(VertexFormat &fmt, uint16_t num) {
			tvb = tfx_transient_buffer_new(&fmt.fmt, num);
		}
	};

	struct Uniform {
		tfx_uniform uniform;
		Uniform(std::string name, tfx_uniform_type type, int count = 1) {
			this->uniform = tfx_uniform_new(name.c_str(), type, count);
		}
	};

	struct Canvas {
		tfx_canvas canvas;
		Canvas(uint16_t w, uint16_t h, tfx_format format = TFX_FORMAT_RGBA8_D16) {
			this->canvas = tfx_canvas_new(w, h, format);
		}
	};

	struct View {
		uint8_t id;
		View(uint8_t _id) {
			this->id = _id;
		}
		inline void set_canvas(Canvas *canvas) {
			tfx_view_set_canvas(this->id, &canvas->canvas);
		}
		inline void set_clear_color(int color = 0x000000ff) {
			tfx_view_set_clear_color(this->id, color);
		}
		inline void set_clear_depth(float depth = 1.0f) {
			tfx_view_set_clear_depth(this->id, depth);
		}
		inline void set_depth_test(tfx_depth_test mode = TFX_DEPTH_TEST_NONE) {
			tfx_view_set_depth_test(this->id, mode);
		}
		inline void set_scissor(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
			tfx_view_set_scissor(this->id, x, y, w, h);
		}
		inline uint16_t get_width() {
			return tfx_view_get_width(this->id);
		}
		inline uint16_t get_height() {
			return tfx_view_get_width(this->id);
		}
		inline void get_dimensions(uint16_t *w, uint16_t *h) {
			tfx_view_get_dimensions(this->id, w, h);
		}
		inline void touch() {
			tfx_touch(this->id);
		}
	};

	struct Texture {
		tfx_texture texture;
		Texture(uint16_t w, uint16_t h, void *data = NULL, bool gen_mips = true, tfx_format format = TFX_FORMAT_RGBA8, uint16_t flags = TFX_TEXTURE_FILTER_LINEAR) {
			this->texture = tfx_texture_new(w, h, data, gen_mips, format, flags);
		}
	};

	struct Program {
		tfx_program program;
		Program(std::string vss, std::string fss, const char *attribs[]) {
			this->program = tfx_program_new(vss.c_str(), fss.c_str(), attribs);
		}
	};

	inline void dump_caps() {
		tfx_dump_caps();
	}
	inline tfx_caps get_caps() {
		return tfx_get_caps();
	}
	inline void touch(uint8_t id) {
		tfx_touch(id);
	}
	inline void reset(uint16_t width, uint16_t height) {
		tfx_reset(width, height);
	}
	inline void shutdown() {
		tfx_shutdown();
	}
	inline tfx_stats frame() {
		return tfx_frame();
	}
	inline void set_uniform(Uniform &uniform, float data) {
		float tmp = data;
		tfx_set_uniform(&uniform.uniform, &tmp);
	}
	inline void set_uniform(Uniform &uniform, float *data) {
		tfx_set_uniform(&uniform.uniform, data);
	}
	inline void set_texture(Uniform &uniform, Texture &texture, uint8_t slot) {
		tfx_set_texture(&uniform.uniform, &texture.texture, slot);
	}
	inline void set_callback(tfx_draw_callback cb) {
		tfx_set_callback(cb);
	}
	inline void set_state(uint64_t flags) {
		tfx_set_state(flags);
	}
	template <typename T>
	inline void set_transient_buffer(TransientBuffer<T> tvb) {
		tfx_set_transient_buffer(tvb.tvb);
	}
	template <typename T>
	inline void set_vertices(Buffer<T> &vbo, int count = 0) {
		tfx_set_vertices(&vbo.buffer, count);
	}
	template <typename T>
	inline void set_indices(Buffer<T> &ibo, int count) {
		tfx_set_indices(&ibo.buffer, count);
	}
	inline void submit(uint8_t id, Program &program, bool retain = false) {
		tfx_submit(id, program.program, retain);
	}
	inline void submit(View &view, Program &program, bool retain = false) {
		tfx_submit(view.id, program.program, retain);
	}
	// inline void blit(tfx_view *src, tfx_view *dst, uint16_t x, uint16_t y, uint16_t w, uint16_t h);

} // tfx
<|endoftext|>


<commit_before>#pragma once

#include <stdint.h>
#include <array>
#include <memory>
#include <functional>

#include <Memory.hpp>

// The NES CPU, the 2A03 (or 2A07 for PAL), is based on the 6502.
class CPU {
public:
    CPU(Memory* mem);

    // Execute next instruction.
    void step();

private:
    void execute(const uint8_t& opcode);

    // Push value on the stack and decrement stack pointer.
    void push(const uint8_t& value);
    // Increment stack pointer and pop value from the stack.
    uint8_t pop();

    // Return 16-bit value concatenated, from 8-bit values at address+1 and address,
    // with bitwise OR in little endian order.
    uint16_t read16(const uint16_t& address);
    // Splits 16-bit value into two 8-bit values and push them to stack.
    void push16(const uint16_t& value);
    // Pops two 8-bit values and returns them concatenated as a 16-bit value.
    uint16_t pop16();

    Memory* memory;

    // Tracks number of emulated cycles.
    int cycles;

    // The following are the registers - denoted with the 'r_' prefix.
    // Accumulator. Used for arithmethical and logical operations.
    uint8_t r_a;
    // Index registers. Used for indexed addressing.
    uint8_t r_x, // Can directly alter stack pointer, unlike 'r_y'.
            r_y;
    // Program Counter. Contains the memory address of the next instruction to be executed.
    uint16_t r_pc;
    // Stack Pointer.
    uint8_t r_sp;
    // Status register.
    // Each bit is a boolean flag. Enumerating the bits:
    // 76543210
    // NV-BDIZC
    // (with 0 being the least significant bit)
    // 0: Carry flag.
    // 1: Zero flag. Set if the result of the last instruction was 0.
    // 2: Interrupt inhibit. Disables response to maskable Interrupt Requests (IRQs). Doesn't affect Non-Maskable Interrupts (NMIs)
    // 3: Decimal mode. Would enable BCD (Binary Coded Decimal) mode, but it's disabled on the 2A03.
    // 4: Break Command.
    // 5: (Unused)
    // 6: Overflow flag.
    // 7: Negative flag. Set if the result of the last operation was negative.
    // TODO: Add interface to status flags
    uint8_t r_p;

    // Addressing Modes
    void implied(void (CPU::*instruction)()) {
        ++r_pc;
        (this->*instruction)();
    }
    void accumulator(void (CPU::*instruction)()) { // Special type of 'implied'. May be unnecessary.
        ++r_pc;
        (this->*instruction)();
    }
    //void immediate(Instruction instruction);
    //void zeroPage(Instruction instruction);
    //void zeroPageX(Instruction instruction);
    //void zeroPageY(Instruction instruction);
    //void relative(Instruction instruction);
    void absolute(void (CPU::*instruction)(const uint16_t&)) {
        const uint16_t address = read16(r_pc + 1);
        r_pc += 3;
        (this->*instruction)(address);
    }
    //void absoluteX(Instruction instruction);
    //void absoluteY(Instruction instruction);
    //void indirect(Instruction instruction);
    //void indexedIndirect(Instruction instruction);
    //void indirectIndexed(Instruction instruction);

    // Instructions
    void ADC(); // Add with Carry
    void AND(); // Logical AND
    void ASL(); // Arithmetic Shift Left
    void BCC(); // Branch if Carry Clear
    void BCS(); // Branch if Carry Set
    void BEQ(); // Branch if Equal
    void BIT(); // Bit Test
    void BMI(); // Branch if Minus
    void BNE(); // Branch if Not Equal
    void BPL(); // Branch if Positive
    void BRK(); // Force Interrupt
    void BVC(); // Branch if Overflow Clear
    void BVS(); // Branch if Overflow Set
    void CLC(); // Clear Carry Flag
    void CLD(); // Clear Decimal Mode
    void CLI(); // Clear Interrupt Disable
    void CLV(); // Clear Overflow Flag
    void CMP(); // Compare
    void CPX(); // Compare X Register
    void CPY(); // Compare Y Register
    void DEC(); // Decrement Memory
    void DEX(); // Decrement X Register
    void DEY(); // Decrement Y Register
    void EOR(); // Exclusive OR
    void INC(); // Increment Memory
    void INX(); // Increment X Register
    void INY(); // Increment Y Register
    void JMP(); // Jump
    void JSR(); // Jump to Subroutine
    void LDA(); // Load Accumulator
    void LDX(); // Load X Register
    void LDY(); // Load Y Register
    void LSR(); // Logical Shift Right
    void NOP(); // No Operation
    void ORA(); // Logical Inclusive OR
    void PHA(); // Push Accumulator
    void PHP(); // Push Processor Status
    void PLA(); // Pull Accumulator
    void PLP(); // Pull Processor Status
    void ROL(); // Rotate Left
    void ROR(); // Rotate Right
    void RTI(); // Return from Interrupt
    void RTS(); // Return from Subroutine
    void SBC(); // Subtract with Carry
    void SEC(); // Set Carry Flag
    void SED(); // Set Decimal Flag
    void SEI(); // Set Interrupt Disable
    void STA(); // Store Accumulator
    void STX(); // Store X Register
    void STY(); // Store Y Register
    void TAX(); // Transfer Accumulator to X
    void TAY(); // Transfer Accumulator to Y
    void TSX(); // Transfer Stack Pointer to X
    void TXA(); // Transfer X to Accumulator
    void TXS(); // Transfer X to Stack Pointer
    void TYA(); // Transfer Y to Accumulator
};<commit_msg>Add CPU addressing mode Immediate<commit_after>#pragma once

#include <stdint.h>
#include <array>
#include <memory>
#include <functional>

#include <Memory.hpp>

// The NES CPU, the 2A03 (or 2A07 for PAL), is based on the 6502.
class CPU {
public:
    CPU(Memory* mem);

    // Execute next instruction.
    void step();

private:
    void execute(const uint8_t& opcode);

    // Push value on the stack and decrement stack pointer.
    void push(const uint8_t& value);
    // Increment stack pointer and pop value from the stack.
    uint8_t pop();

    // Return 16-bit value concatenated, from 8-bit values at address+1 and address,
    // with bitwise OR in little endian order.
    uint16_t read16(const uint16_t& address);
    // Splits 16-bit value into two 8-bit values and push them to stack.
    void push16(const uint16_t& value);
    // Pops two 8-bit values and returns them concatenated as a 16-bit value.
    uint16_t pop16();

    Memory* memory;

    // Tracks number of emulated cycles.
    int cycles;

    // The following are the registers - denoted with the 'r_' prefix.
    // Accumulator. Used for arithmethical and logical operations.
    uint8_t r_a;
    // Index registers. Used for indexed addressing.
    uint8_t r_x, // Can directly alter stack pointer, unlike 'r_y'.
            r_y;
    // Program Counter. Contains the memory address of the next instruction to be executed.
    uint16_t r_pc;
    // Stack Pointer.
    uint8_t r_sp;
    // Status register.
    // Each bit is a boolean flag. Enumerating the bits:
    // 76543210
    // NV-BDIZC
    // (with 0 being the least significant bit)
    // 0: Carry flag.
    // 1: Zero flag. Set if the result of the last instruction was 0.
    // 2: Interrupt inhibit. Disables response to maskable Interrupt Requests (IRQs). Doesn't affect Non-Maskable Interrupts (NMIs)
    // 3: Decimal mode. Would enable BCD (Binary Coded Decimal) mode, but it's disabled on the 2A03.
    // 4: Break Command.
    // 5: (Unused)
    // 6: Overflow flag.
    // 7: Negative flag. Set if the result of the last operation was negative.
    // TODO: Add interface to status flags
    uint8_t r_p;

    // Addressing Modes
    void implied(void (CPU::*instruction)()) {
        ++r_pc;
        (this->*instruction)();
    }
    void accumulator(void (CPU::*instruction)()) { // Special type of 'implied'. May be unnecessary.
        ++r_pc;
        (this->*instruction)();
    }
    void immediate(void (CPU::*instruction)(const uint8_t)) {
        const uint8_t value = memory->read(r_pc + 1);
        r_pc += 2;
        (this->*instruction)(value);
    }
    //void zeroPage(Instruction instruction);
    //void zeroPageX(Instruction instruction);
    //void zeroPageY(Instruction instruction);
    //void relative(Instruction instruction);
    void absolute(void (CPU::*instruction)(const uint16_t&)) {
        const uint16_t address = read16(r_pc + 1);
        r_pc += 3;
        (this->*instruction)(address);
    }
    //void absoluteX(Instruction instruction);
    //void absoluteY(Instruction instruction);
    //void indirect(Instruction instruction);
    //void indexedIndirect(Instruction instruction);
    //void indirectIndexed(Instruction instruction);

    // Instructions
    void ADC(); // Add with Carry
    void AND(); // Logical AND
    void ASL(); // Arithmetic Shift Left
    void BCC(); // Branch if Carry Clear
    void BCS(); // Branch if Carry Set
    void BEQ(); // Branch if Equal
    void BIT(); // Bit Test
    void BMI(); // Branch if Minus
    void BNE(); // Branch if Not Equal
    void BPL(); // Branch if Positive
    void BRK(); // Force Interrupt
    void BVC(); // Branch if Overflow Clear
    void BVS(); // Branch if Overflow Set
    void CLC(); // Clear Carry Flag
    void CLD(); // Clear Decimal Mode
    void CLI(); // Clear Interrupt Disable
    void CLV(); // Clear Overflow Flag
    void CMP(); // Compare
    void CPX(); // Compare X Register
    void CPY(); // Compare Y Register
    void DEC(); // Decrement Memory
    void DEX(); // Decrement X Register
    void DEY(); // Decrement Y Register
    void EOR(); // Exclusive OR
    void INC(); // Increment Memory
    void INX(); // Increment X Register
    void INY(); // Increment Y Register
    void JMP(); // Jump
    void JSR(); // Jump to Subroutine
    void LDA(); // Load Accumulator
    void LDX(); // Load X Register
    void LDY(); // Load Y Register
    void LSR(); // Logical Shift Right
    void NOP(); // No Operation
    void ORA(); // Logical Inclusive OR
    void PHA(); // Push Accumulator
    void PHP(); // Push Processor Status
    void PLA(); // Pull Accumulator
    void PLP(); // Pull Processor Status
    void ROL(); // Rotate Left
    void ROR(); // Rotate Right
    void RTI(); // Return from Interrupt
    void RTS(); // Return from Subroutine
    void SBC(); // Subtract with Carry
    void SEC(); // Set Carry Flag
    void SED(); // Set Decimal Flag
    void SEI(); // Set Interrupt Disable
    void STA(); // Store Accumulator
    void STX(); // Store X Register
    void STY(); // Store Y Register
    void TAX(); // Transfer Accumulator to X
    void TAY(); // Transfer Accumulator to Y
    void TSX(); // Transfer Stack Pointer to X
    void TXA(); // Transfer X to Accumulator
    void TXS(); // Transfer X to Stack Pointer
    void TYA(); // Transfer Y to Accumulator
};<|endoftext|>


<commit_before>/*
 * Copyright 2012 Esrille 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 <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/Atoms.h>

#include <string>

// Since glutSetWindowTitle() only accpets a string in ASCII code,
// we have to implement our own version for now.
void setWindowTitle(const std::string& title)
{
    XTextProperty text;
    text.value = (unsigned char*) title.c_str();
    text.encoding = XA_UTF8_STRING(glXGetCurrentDisplay());
    text.format = 8;
    text.nitems = title.length();
    XSetWMName(glXGetCurrentDisplay(), glXGetCurrentDrawable(), &text);
}

void setIcon(size_t n, size_t width, size_t height, uint32_t* image)
{
    Atom netWmIcon = XInternAtom(glXGetCurrentDisplay(), "_NET_WM_ICON", False);
    Atom cardinal = XInternAtom(glXGetCurrentDisplay(), "CARDINAL", False);
    size_t length = 2 + width * height;
    long buffer[length];
    buffer[0] = width;
    buffer[1] = height;
    for (size_t i = 0; i < width * height; ++i) {
        // Convert RGBA (OpenGL) to ARGB (X11); i.e., swap R and B.
        uint32_t argb = image[i] & 0xff00ff00;
        argb |= (image[i] >> 16) & 0x000000ff;
        argb |= (image[i] << 16) & 0x00ff0000;
        buffer[2 + i] = argb;
    }
    XChangeProperty(glXGetCurrentDisplay(), glXGetCurrentDrawable(), netWmIcon, cardinal, 32,
                    (n == 0) ? PropModeReplace : PropModeAppend,
                    reinterpret_cast<const unsigned char*>(buffer), length);
    XFlush(glXGetCurrentDisplay());
}
<commit_msg>(setWindowTitle) : Use _NET_WM_NAME for old window managers just in case.<commit_after>/*
 * Copyright 2012 Esrille 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 <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xmu/Atoms.h>

#include <string>

// Since glutSetWindowTitle() only accpets a string in ASCII code,
// we have to implement our own version for now.
void setWindowTitle(const std::string& title)
{
    Atom name = XInternAtom(glXGetCurrentDisplay(), "_NET_WM_NAME", False);
    Atom utf8 = XInternAtom(glXGetCurrentDisplay(), "UTF8_STRING", False);
    XChangeProperty(glXGetCurrentDisplay(), glXGetCurrentDrawable(), name, utf8,
                    8, PropModeReplace, (unsigned char*) title.c_str(),
                    title.length());
}

void setIcon(size_t n, size_t width, size_t height, uint32_t* image)
{
    Atom netWmIcon = XInternAtom(glXGetCurrentDisplay(), "_NET_WM_ICON", False);
    Atom cardinal = XInternAtom(glXGetCurrentDisplay(), "CARDINAL", False);
    size_t length = 2 + width * height;
    long buffer[length];
    buffer[0] = width;
    buffer[1] = height;
    for (size_t i = 0; i < width * height; ++i) {
        // Convert RGBA (OpenGL) to ARGB (X11); i.e., swap R and B.
        uint32_t argb = image[i] & 0xff00ff00;
        argb |= (image[i] >> 16) & 0x000000ff;
        argb |= (image[i] << 16) & 0x00ff0000;
        buffer[2 + i] = argb;
    }
    XChangeProperty(glXGetCurrentDisplay(), glXGetCurrentDrawable(), netWmIcon, cardinal, 32,
                    (n == 0) ? PropModeReplace : PropModeAppend,
                    reinterpret_cast<const unsigned char*>(buffer), length);
    XFlush(glXGetCurrentDisplay());
}
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <vector>
#include <string>
#include <cmath>
#include <map>
#include <fstream>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrConf {
public:
  snrConf();
  ~snrConf();
  // Get
  unsigned int getNrThreadsD0() const;
  unsigned int getNrItemsD0() const;
  // Set
  void setNrThreadsD0(unsigned int threads);
  void setNrItemsD0(unsigned int items);
  // utils
  std::string print() const;

private:
  unsigned int nrThreadsD0;
  unsigned int nrItemsD0;
};

typedef std::map< std::string, std::map< unsigned int, std::map< unsigned int, PulsarSearch::snrConf * > * > * > tunedSNRConf;

// OpenCL SNR
template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding);
template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding);
// Read configuration files
void readTunedSNRConf(tunedSNRConf & tunedSNR, const std::string & snrFilename);

// Implementations
inline unsigned int snrConf::getNrThreadsD0() const {
  return nrThreadsD0;
}

inline unsigned int snrConf::getNrItemsD0() const {
  return nrItemsD0;
}

inline void snrConf::setNrThreadsD0(unsigned int threads) {
  nrThreadsD0 = threads;
}

inline void snrConf::setNrItemsD0(unsigned int items) {
  nrItemsD0 = items;
}

template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrDMsSamples" + isa::utils::toString(nrSamples) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = get_group_id(1);\n"
    "float delta = 0.0f;\n"
    "__local float reductionCOU[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local " + dataName + " reductionMAX[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionMEA[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionVAR[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "<%DEF%>"
    "\n"
    "// Compute phase\n"
    "for ( unsigned int sample = get_local_id(0) + " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + "; sample < " + isa::utils::toString(nrSamples) + "; sample += " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + " ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "// In-thread reduce\n"
    "<%REDUCE%>"
    "// Local memory store\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "// Reduce phase\n"
    "unsigned int threshold = " + isa::utils::toString(conf.getNrThreadsD0() / 2) + ";\n"
    "for ( unsigned int sample = get_local_id(0); threshold > 0; threshold /= 2 ) {\n"
    "if ( sample < threshold ) {\n"
    "delta = reductionMEA[sample + threshold] - mean0;\n"
    "counter0 += reductionCOU[sample + threshold];\n"
    "max0 = fmax(max0, reductionMAX[sample + threshold]);\n"
    "mean0 = ((reductionCOU[sample] * mean0) + (reductionCOU[sample + threshold] * reductionMEA[sample + threshold])) / counter0;\n"
    "variance0 += reductionVAR[sample + threshold] + ((delta * delta) * ((reductionCOU[sample] * reductionCOU[sample + threshold]) / counter0));\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "}\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "}\n"
    "// Store\n"
    "if ( get_local_id(0) == 0 ) {\n"
    "output[dm] = (max0 - mean0) / native_sqrt(variance0 * " + isa::utils::toString(1.0f / (nrSamples - 1)) + "f);\n"
    "}\n"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (get_local_id(0) + <%OFFSET%>)];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "if ( sample + <%OFFSET%> < " + isa::utils::toString(nrSamples) + " ) {\n"
    "item = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (sample + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n"
    "}\n";
  std::string reduce_sTemplate = "delta = mean<%NUM%> - mean0;\n"
    "counter0 += counter<%NUM%>;\n"
    "max0 = fmax(max0, max<%NUM%>);\n"
    "mean0 = (((counter0 - counter<%NUM%>) * mean0) + (counter<%NUM%> * mean<%NUM%>)) / counter0;\n"
    "variance0 += variance<%NUM%> + ((delta * delta) * (((counter0 - counter<%NUM%>) * counter<%NUM%>) / counter0));\n";
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();

  for ( unsigned int sample = 0; sample < conf.getNrItemsD0(); sample++ ) {
    std::string sample_s = isa::utils::toString(sample);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * sample);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    if ( sample == 0 ) {
      continue;
    }
    temp = isa::utils::replace(&reduce_sTemplate, "<%NUM%>", sample_s);
    reduce_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  delete def_s;
  delete compute_s;
  delete reduce_s;

  return code;
}

template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrSamplesDMs" + isa::utils::toString(observation.getNrDMs()) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = (" + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0);\n"
    "float delta = 0.0f;\n"
    "<%DEF%>"
    "\n"
    "for ( unsigned int sample = 1; sample < " + isa::utils::toString(observation.getNrSamplesPerSecond()) + "; sample++ ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "<%STORE%>"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[dm + <%OFFSET%>];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(sample * " + isa::utils::toString(observation.getNrPaddedDMs(padding / sizeof(T))) + ")  + (dm + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string store_sTemplate;
  if ( dataName == "double" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0 / (observation.getNrSamplesPerSecond() - 1)) + ");\n";
  } else if ( dataName == "float" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0f / (observation.getNrSamplesPerSecond() - 1)) + "f);\n";
  } else {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> / " + isa::utils::toString(observation.getNrSamplesPerSecond() - 1) + "f);\n";
  }
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * store_s = new std::string();

  for ( unsigned int dm = 0; dm < conf.getNrItemsD0(); dm++ ) {
    std::string dm_s = isa::utils::toString(dm);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * dm);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&store_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete def_s;
  delete compute_s;
  delete store_s;

  return code;
}

} // PulsarSearch

#endif // SNR_HPP

<commit_msg>Fixing a bug in snrSamplesDMs.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <vector>
#include <string>
#include <cmath>
#include <map>
#include <fstream>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrConf {
public:
  snrConf();
  ~snrConf();
  // Get
  unsigned int getNrThreadsD0() const;
  unsigned int getNrItemsD0() const;
  // Set
  void setNrThreadsD0(unsigned int threads);
  void setNrItemsD0(unsigned int items);
  // utils
  std::string print() const;

private:
  unsigned int nrThreadsD0;
  unsigned int nrItemsD0;
};

typedef std::map< std::string, std::map< unsigned int, std::map< unsigned int, PulsarSearch::snrConf * > * > * > tunedSNRConf;

// OpenCL SNR
template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding);
template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding);
// Read configuration files
void readTunedSNRConf(tunedSNRConf & tunedSNR, const std::string & snrFilename);

// Implementations
inline unsigned int snrConf::getNrThreadsD0() const {
  return nrThreadsD0;
}

inline unsigned int snrConf::getNrItemsD0() const {
  return nrItemsD0;
}

inline void snrConf::setNrThreadsD0(unsigned int threads) {
  nrThreadsD0 = threads;
}

inline void snrConf::setNrItemsD0(unsigned int items) {
  nrItemsD0 = items;
}

template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrDMsSamples" + isa::utils::toString(nrSamples) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = get_group_id(1);\n"
    "float delta = 0.0f;\n"
    "__local float reductionCOU[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local " + dataName + " reductionMAX[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionMEA[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionVAR[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "<%DEF%>"
    "\n"
    "// Compute phase\n"
    "for ( unsigned int sample = get_local_id(0) + " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + "; sample < " + isa::utils::toString(nrSamples) + "; sample += " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + " ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "// In-thread reduce\n"
    "<%REDUCE%>"
    "// Local memory store\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "// Reduce phase\n"
    "unsigned int threshold = " + isa::utils::toString(conf.getNrThreadsD0() / 2) + ";\n"
    "for ( unsigned int sample = get_local_id(0); threshold > 0; threshold /= 2 ) {\n"
    "if ( sample < threshold ) {\n"
    "delta = reductionMEA[sample + threshold] - mean0;\n"
    "counter0 += reductionCOU[sample + threshold];\n"
    "max0 = fmax(max0, reductionMAX[sample + threshold]);\n"
    "mean0 = ((reductionCOU[sample] * mean0) + (reductionCOU[sample + threshold] * reductionMEA[sample + threshold])) / counter0;\n"
    "variance0 += reductionVAR[sample + threshold] + ((delta * delta) * ((reductionCOU[sample] * reductionCOU[sample + threshold]) / counter0));\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "}\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "}\n"
    "// Store\n"
    "if ( get_local_id(0) == 0 ) {\n"
    "output[dm] = (max0 - mean0) / native_sqrt(variance0 * " + isa::utils::toString(1.0f / (nrSamples - 1)) + "f);\n"
    "}\n"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (get_local_id(0) + <%OFFSET%>)];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "if ( sample + <%OFFSET%> < " + isa::utils::toString(nrSamples) + " ) {\n"
    "item = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (sample + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n"
    "}\n";
  std::string reduce_sTemplate = "delta = mean<%NUM%> - mean0;\n"
    "counter0 += counter<%NUM%>;\n"
    "max0 = fmax(max0, max<%NUM%>);\n"
    "mean0 = (((counter0 - counter<%NUM%>) * mean0) + (counter<%NUM%> * mean<%NUM%>)) / counter0;\n"
    "variance0 += variance<%NUM%> + ((delta * delta) * (((counter0 - counter<%NUM%>) * counter<%NUM%>) / counter0));\n";
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();

  for ( unsigned int sample = 0; sample < conf.getNrItemsD0(); sample++ ) {
    std::string sample_s = isa::utils::toString(sample);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * sample);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    if ( sample == 0 ) {
      continue;
    }
    temp = isa::utils::replace(&reduce_sTemplate, "<%NUM%>", sample_s);
    reduce_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  delete def_s;
  delete compute_s;
  delete reduce_s;

  return code;
}

template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrSamplesDMs" + isa::utils::toString(observation.getNrDMs()) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = (get_group_id(0) * " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0);\n"
    "float delta = 0.0f;\n"
    "<%DEF%>"
    "\n"
    "for ( unsigned int sample = 1; sample < " + isa::utils::toString(observation.getNrSamplesPerSecond()) + "; sample++ ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "<%STORE%>"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[dm + <%OFFSET%>];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(sample * " + isa::utils::toString(observation.getNrPaddedDMs(padding / sizeof(T))) + ")  + (dm + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string store_sTemplate;
  if ( dataName == "double" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0 / (observation.getNrSamplesPerSecond() - 1)) + ");\n";
  } else if ( dataName == "float" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0f / (observation.getNrSamplesPerSecond() - 1)) + "f);\n";
  } else {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> / " + isa::utils::toString(observation.getNrSamplesPerSecond() - 1) + "f);\n";
  }
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * store_s = new std::string();

  for ( unsigned int dm = 0; dm < conf.getNrItemsD0(); dm++ ) {
    std::string dm_s = isa::utils::toString(dm);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * dm);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&store_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete def_s;
  delete compute_s;
  delete store_s;

  return code;
}

} // PulsarSearch

#endif // SNR_HPP

<|endoftext|>