<commit_before>// HoldTheFlag.cpp : bzfs plugin for Hold-The-flag game mode
//
// $Id$

#include "bzfsAPI.h"
#include <map>
#include <stdarg.h>

BZ_GET_PLUGIN_VERSION

#define HOLDTHEFLAG_VER "1.00.02"
#define DO_FLAG_RESET 1
#define DEFAULT_TEAM eGreenTeam

#define MAX_PLAYERID 255

#ifdef _WIN32

#ifndef strcasecmp
#  define strcasecmp _stricmp
#endif

#ifndef strncasecmp
#  define strncasecmp _strnicmp
#endif

#endif

typedef struct {
  bool isValid;
  int  score;
  char callsign[22];
  double  joinTime;
  int capNum;
} HtfPlayer;

HtfPlayer Players[MAX_PLAYERID+1];
std::map<std::string, HtfPlayer> leftDuringMatch;
bool matchActive = false;
bool htfEnabled = true;
bz_eTeamType htfTeam = eNoTeam;
int nextCapNum = 0;
int NumPlayers=0;
int Leader;

class HTFscore : public bz_EventHandler, public bz_CustomSlashCommandHandler
{
public:
  virtual void process ( bz_EventData *eventData );
  virtual bool handle ( int playerID, bz_ApiString, bz_ApiString, bz_APIStringList*);
  bz_eTeamType colorNameToDef (const char *color);
  const char *colorDefToName (bz_eTeamType team);

protected:

private:
};

HTFscore htfScore;

bz_eTeamType HTFscore::colorNameToDef (const char *color)
{
  if (!color && (strlen(color)<3))
	return eNoTeam;

  char temp[4] = {0};
  strncpy(temp,color,3);

  if (!strcasecmp (color, "gre"))
    return eGreenTeam;
  if (!strcasecmp (color, "red"))
    return eRedTeam;
  if (!strcasecmp (color, "pur"))
    return ePurpleTeam;
  if (!strcasecmp (color, "blu"))
    return eBlueTeam;
  if (!strcasecmp (color, "rog"))
    return eRogueTeam;
  if (!strcasecmp (color, "obs"))
    return eObservers;
  return eNoTeam;
}

const char *HTFscore::colorDefToName (bz_eTeamType team)
{
  switch (team){
    case eGreenTeam:
      return ("Green");
    case eBlueTeam:
      return ("Blue");
    case eRedTeam:
      return ("Red");
    case ePurpleTeam:
      return ("Purple");
    case eObservers:
      return ("Observer");
    case eRogueTeam:
      return ("Rogue");
    case eRabbitTeam:
      return ("Rabbit");
    case eHunterTeam:
      return ("Hunters");
    case eAdministrators:
      return ("Administrators");
    default:
      return ("No Team");
  }
}

bool listAdd (int playerID, const char *callsign)
{
  if (playerID>MAX_PLAYERID || playerID<0)
    return false;
  Players[playerID].score = 0;
  Players[playerID].isValid = true;
  Players[playerID].capNum = -1;
  strncpy (Players[playerID].callsign, callsign, 20);
  ++NumPlayers;
  return true;
}

bool listDel (int playerID){
  if (playerID>MAX_PLAYERID || playerID<0 || !Players[playerID].isValid)
    return false;
  Players[playerID].isValid = false;
  --NumPlayers;
  return true;
}

int sort_compare (const void *_p1, const void *_p2){
  int p1 = *(int *)_p1;
  int p2 = *(int *)_p2;

  if (Players[p1].score != Players[p2].score)
    return Players[p2].score - Players[p1].score;
  return Players[p2].capNum - Players[p1].capNum;
  return 0;
}

void dispScores (int who)
{
  int sortList[MAX_PLAYERID+1];	 // do HtfPlayer *   !!
  int playerLastCapped = -1;
  int lastCapnum = -1;
  int x = 0;

  if (!htfEnabled)
    return;
  bz_sendTextMessage(BZ_SERVER, who, "**** HTF  Scoreboard ****");
  Leader = -1;
  if (NumPlayers<1)
    return;

  for (int i=0; i<MAX_PLAYERID; i++){
    if (Players[i].isValid) {
      if (Players[i].capNum > lastCapnum){
	playerLastCapped = i;
	lastCapnum = Players[i].capNum;
      }
      sortList[x++] = i;
    }
  }
  qsort (sortList, NumPlayers, sizeof(int), sort_compare);
  if (x != NumPlayers)
    bz_debugMessage(1, "++++++++++++++++++++++++ HTF INTERNAL ERROR: player count mismatch!");
  for (int i=0; i<NumPlayers; i++){
    x = sortList[i];
    bz_sendTextMessagef(BZ_SERVER, who, "%20.20s :%3d %c", Players[x].callsign, Players[x].score,
			x == playerLastCapped ? '*' : ' ');
  }
  Leader = sortList[0];
}

void resetScores (void)
{
  for (int i=0; i<MAX_PLAYERID; i++){
    Players[i].score = 0;
    Players[i].capNum = -1;
  }
  nextCapNum = 0;
}

void htfCapture (int who)
{
  if (!htfEnabled)
    return;

#if DO_FLAG_RESET
  bz_resetFlags ( false );
#endif

  bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "HTF FLAG CAPTURED by %s", Players[who].callsign);
  ++Players[who].score;
  Players[who].capNum = nextCapNum++;
  dispScores(BZ_ALLUSERS);
}

void htfStartGame (void)
{
  if (!htfEnabled)
    return;

// TODO: clear leftDuringMatch
  resetScores();
  matchActive = true;
  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "HTF MATCH has begun, good luck!");
}

void htfEndGame (void)
{
  if (htfEnabled && matchActive){
    dispScores(BZ_ALLUSERS);
    bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "HTF MATCH has ended.");
    if (Leader >= 0)
      bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "%s is the WINNER !", Players[Leader].callsign);
  }

  matchActive = false;

// TODO: clear leftDuringMatch

}

void sendHelp (int who)
{
  bz_sendTextMessage(BZ_SERVER, who, "HTF commands: reset, off, on, stats");
}

/************************** (SUB)COMMAND Implementations ... **************************/

void htfStats (int who)
{
  bz_sendTextMessagef(BZ_SERVER, who, "HTF plugin version %s", HOLDTHEFLAG_VER);
  bz_sendTextMessagef(BZ_SERVER, who,  "  Team: %s", htfScore.colorDefToName(htfTeam));
  bz_sendTextMessagef(BZ_SERVER, who,  "  Flag Reset: %s" , DO_FLAG_RESET ? "ENabled":"DISabled");
}

void htfReset (int who)
{
  resetScores();
  bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "*** HTF scores reset by %s", Players[who].callsign);
}

void htfEnable (bool onoff, int who)
{
  char msg[255];
  if (onoff == htfEnabled){
    bz_sendTextMessage(BZ_SERVER, who, "HTF mode is already that way.");
    return;
  }
  htfEnabled = onoff;
  sprintf (msg, "*** HTF mode %s by %s", onoff?"ENabled":"DISabled", Players[who].callsign);
  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, msg);
}

// handle events
void HTFscore::process ( bz_EventData *eventData )
{
  // player JOIN
  if (eventData->eventType == bz_ePlayerJoinEvent) {
    char msg[255];
    bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData;
bz_debugMessagef(3, "++++++ HTFscore: Player JOINED (ID:%d, TEAM:%d, CALLSIGN:%s)", joinData->playerID, joinData->record->team, joinData->record->callsign.c_str()); fflush (stdout);
    if (htfTeam!=eNoTeam && joinData->record->team!=htfTeam && joinData->record->team != eObservers){
      sprintf (msg, "HTF mode enabled, you must join the %s team to play", htfScore.colorDefToName(htfTeam));
      bz_kickUser (joinData->record->playerID, msg, true);
      return;
    }
    if (joinData->record->team == htfTeam)
      listAdd (joinData->playerID, joinData->record->callsign.c_str());

  // player PART
  } else if (eventData->eventType == bz_ePlayerPartEvent) {
    bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData;
bz_debugMessagef(3, "++++++ HTFscore: Player PARTED (ID:%d, TEAM:%d, CALLSIGN:%s)", joinData->playerID, joinData->record->team, joinData->record->callsign.c_str()); fflush (stdout);

    if (joinData->record->team == htfTeam)
      listDel (joinData->playerID);

  // flag CAPTURE
  } else if (eventData->eventType == bz_eCaptureEvent) {
    bz_CTFCaptureEventData_V1 *capData = (bz_CTFCaptureEventData_V1*)eventData;
    htfCapture (capData->playerCapping);

  // game START
  } else if (eventData->eventType == bz_eGameStartEvent) {
    bz_GameStartEndEventData_V1 *msgData = (bz_GameStartEndEventData_V1*)eventData;
bz_debugMessagef(2, "++++++ HTFscore: Game START (%f, %f)", msgData->eventTime, msgData->duration); fflush (stdout);
    htfStartGame ();

  // game END
  } else if (eventData->eventType == bz_eGameEndEvent) {
    bz_GameStartEndEventData_V1 *msgData = (bz_GameStartEndEventData_V1*)eventData;
bz_debugMessagef(2, "++++++ HTFscore: Game END (%f, %f)", msgData->eventTime, msgData->duration); fflush (stdout);
    htfEndGame ();
  }
}

bool checkPerms (int playerID, const char *htfCmd, const char *permName)
{
  if (bz_hasPerm (playerID, permName))
    return true;
  bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "you need \"%s\" permission to do /htf %s", permName, htfCmd);
  return false;
}

// handle /htf command
bool HTFscore::handle ( int playerID, bz_ApiString cmd, bz_ApiString, bz_APIStringList* cmdParams )
{
  char subCmd[6];
  if (strcasecmp (cmd.c_str(), "htf"))   // is it for me ?
    return false;
  if (cmdParams->get(0).c_str()[0] == '\0'){
    dispScores (playerID);
    return true;
  }

  strncpy (subCmd, cmdParams->get(0).c_str(), 5);
  subCmd[4] = '\0';
  if (strcasecmp (subCmd, "rese") == 0){
    if (checkPerms (playerID, "reset", "COUNTDOWN"))
      htfReset (playerID);
  } else if (strcasecmp (subCmd, "off") == 0){
    if (checkPerms (playerID, "off", "HTFONOFF"))
      htfEnable (false, playerID);
  } else if (strcasecmp (subCmd, "on") == 0){
    if (checkPerms (playerID, "off", "HTFONOFF"))
      htfEnable (true, playerID);
  } else if (strcasecmp (subCmd, "stat") == 0)
    htfStats (playerID);
  else
    sendHelp (playerID);
  return true;
}

bool commandLineHelp (void){
  const char *help[] = {
    "Command line args:  PLUGINNAME,[TEAM=color]",
    NULL
  };
  bz_debugMessage (0, "+++ HoldTheFlag plugin command-line error");
  for (int x=0; help[x]!=NULL; x++)
    bz_debugMessage (0, help[x]);
  return true;
}

bool parseCommandLine (const char *cmdLine)
{
  if (cmdLine==NULL || *cmdLine=='\0' || strlen(cmdLine) < 5 )
    return false;
  htfTeam = eGreenTeam;
  if (strncasecmp (cmdLine, "TEAM=", 5) == 0){
    if ((htfTeam = htfScore.colorNameToDef(cmdLine+5)) == eNoTeam)
      return commandLineHelp ();
  } else
    return commandLineHelp ();
  return false;
}

BZF_PLUGIN_CALL int bz_Load (const char* cmdLine)
{
  bz_BasePlayerRecord *playerRecord;

  if (parseCommandLine (cmdLine))
    return -1;

  // get current list of player indices ...
  bz_APIIntList *playerList = bz_newIntList();
  bz_getPlayerIndexList (playerList);
  for (unsigned int i = 0; i < playerList->size(); i++){
    if ((playerRecord = bz_getPlayerByIndex (playerList->get(i))) != NULL){
      listAdd (playerList->get(i), playerRecord->callsign.c_str());
      bz_freePlayerRecord (playerRecord);
    }
  }
  bz_deleteIntList (playerList);

  bz_registerCustomSlashCommand ("htf", &htfScore);
  bz_registerEvent(bz_ePlayerJoinEvent, &htfScore);
  bz_registerEvent(bz_ePlayerPartEvent, &htfScore);
  bz_registerEvent(bz_eCaptureEvent, &htfScore);
  bz_registerEvent(bz_eGameStartEvent, &htfScore);
  bz_registerEvent(bz_eGameEndEvent, &htfScore);
  bz_debugMessagef(1, "HoldTheFlag plugin loaded - v%s", HOLDTHEFLAG_VER);
  return 0;
}

BZF_PLUGIN_CALL int bz_Unload (void)
{
  bz_removeCustomSlashCommand ("htf");
  bz_removeEvent (bz_ePlayerJoinEvent, &htfScore);
  bz_removeEvent (bz_ePlayerPartEvent, &htfScore);
  bz_removeEvent (bz_eCaptureEvent, &htfScore);
  bz_removeEvent (bz_eGameStartEvent, &htfScore);
  bz_removeEvent (bz_eGameEndEvent, &htfScore);
  bz_debugMessage(1, "HoldTheFlag plugin unloaded");
  return 0;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>More whitespace... where will it end?<commit_after>// HoldTheFlag.cpp : bzfs plugin for Hold-The-flag game mode
//
// $Id$

#include "bzfsAPI.h"
#include <map>
#include <stdarg.h>

BZ_GET_PLUGIN_VERSION

#define HOLDTHEFLAG_VER "1.00.02"
#define DO_FLAG_RESET 1
#define DEFAULT_TEAM eGreenTeam

#define MAX_PLAYERID 255

#ifdef _WIN32

#ifndef strcasecmp
#  define strcasecmp _stricmp
#endif

#ifndef strncasecmp
#  define strncasecmp _strnicmp
#endif

#endif

typedef struct {
  bool isValid;
  int  score;
  char callsign[22];
  double  joinTime;
  int capNum;
} HtfPlayer;

HtfPlayer Players[MAX_PLAYERID+1];
std::map<std::string, HtfPlayer> leftDuringMatch;
bool matchActive = false;
bool htfEnabled = true;
bz_eTeamType htfTeam = eNoTeam;
int nextCapNum = 0;
int NumPlayers=0;
int Leader;

class HTFscore : public bz_EventHandler, public bz_CustomSlashCommandHandler
{
public:
  virtual void process(bz_EventData *eventData);
  virtual bool handle(int playerID, bz_ApiString, bz_ApiString, bz_APIStringList*);
  bz_eTeamType colorNameToDef(const char *color);
  const char *colorDefToName(bz_eTeamType team);

protected:

private:
};

HTFscore htfScore;

bz_eTeamType HTFscore::colorNameToDef(const char *color)
{
  if (!color && (strlen(color)<3))
    return eNoTeam;

  char temp[4] = {0};
  strncpy(temp,color,3);

  if (!strcasecmp(color, "gre"))
    return eGreenTeam;
  if (!strcasecmp(color, "red"))
    return eRedTeam;
  if (!strcasecmp(color, "pur"))
    return ePurpleTeam;
  if (!strcasecmp(color, "blu"))
    return eBlueTeam;
  if (!strcasecmp(color, "rog"))
    return eRogueTeam;
  if (!strcasecmp(color, "obs"))
    return eObservers;
  return eNoTeam;
}

const char *HTFscore::colorDefToName(bz_eTeamType team)
{
  switch (team){
  case eGreenTeam:
    return ("Green");
  case eBlueTeam:
    return ("Blue");
  case eRedTeam:
    return ("Red");
  case ePurpleTeam:
    return ("Purple");
  case eObservers:
    return ("Observer");
  case eRogueTeam:
    return ("Rogue");
  case eRabbitTeam:
    return ("Rabbit");
  case eHunterTeam:
    return ("Hunters");
  case eAdministrators:
    return ("Administrators");
  default:
    return ("No Team");
  }
}

bool listAdd(int playerID, const char *callsign)
{
  if (playerID>MAX_PLAYERID || playerID<0)
    return false;
  Players[playerID].score = 0;
  Players[playerID].isValid = true;
  Players[playerID].capNum = -1;
  strncpy(Players[playerID].callsign, callsign, 20);
  ++NumPlayers;
  return true;
}

bool listDel(int playerID){
  if (playerID>MAX_PLAYERID || playerID<0 || !Players[playerID].isValid)
    return false;
  Players[playerID].isValid = false;
  --NumPlayers;
  return true;
}

int sort_compare(const void *_p1, const void *_p2){
  int p1 = *(int *)_p1;
  int p2 = *(int *)_p2;

  if (Players[p1].score != Players[p2].score)
    return Players[p2].score - Players[p1].score;
  return Players[p2].capNum - Players[p1].capNum;
  return 0;
}

void dispScores(int who)
{
  int sortList[MAX_PLAYERID+1];	 // do HtfPlayer *   !!
  int playerLastCapped = -1;
  int lastCapnum = -1;
  int x = 0;

  if (!htfEnabled)
    return;
  bz_sendTextMessage(BZ_SERVER, who, "**** HTF  Scoreboard ****");
  Leader = -1;
  if (NumPlayers<1)
    return;

  for (int i=0; i<MAX_PLAYERID; i++){
    if (Players[i].isValid) {
      if (Players[i].capNum > lastCapnum){
	playerLastCapped = i;
	lastCapnum = Players[i].capNum;
      }
      sortList[x++] = i;
    }
  }
  qsort(sortList, NumPlayers, sizeof(int), sort_compare);
  if (x != NumPlayers)
    bz_debugMessage(1, "++++++++++++++++++++++++ HTF INTERNAL ERROR: player count mismatch!");
  for (int i=0; i<NumPlayers; i++){
    x = sortList[i];
    bz_sendTextMessagef(BZ_SERVER, who, "%20.20s :%3d %c", Players[x].callsign, Players[x].score,
			x == playerLastCapped ? '*' : ' ');
  }
  Leader = sortList[0];
}

void resetScores(void)
{
  for (int i=0; i<MAX_PLAYERID; i++){
    Players[i].score = 0;
    Players[i].capNum = -1;
  }
  nextCapNum = 0;
}

void htfCapture(int who)
{
  if (!htfEnabled)
    return;

#if DO_FLAG_RESET
  bz_resetFlags(false);
#endif

  bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "HTF FLAG CAPTURED by %s", Players[who].callsign);
  ++Players[who].score;
  Players[who].capNum = nextCapNum++;
  dispScores(BZ_ALLUSERS);
}

void htfStartGame(void)
{
  if (!htfEnabled)
    return;

  // TODO: clear leftDuringMatch
  resetScores();
  matchActive = true;
  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "HTF MATCH has begun, good luck!");
}

void htfEndGame(void)
{
  if (htfEnabled && matchActive){
    dispScores(BZ_ALLUSERS);
    bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, "HTF MATCH has ended.");
    if (Leader >= 0)
      bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "%s is the WINNER !", Players[Leader].callsign);
  }

  matchActive = false;

  // TODO: clear leftDuringMatch

}

void sendHelp(int who)
{
  bz_sendTextMessage(BZ_SERVER, who, "HTF commands: reset, off, on, stats");
}

/************************** (SUB)COMMAND Implementations ... **************************/

void htfStats(int who)
{
  bz_sendTextMessagef(BZ_SERVER, who, "HTF plugin version %s", HOLDTHEFLAG_VER);
  bz_sendTextMessagef(BZ_SERVER, who,  "  Team: %s", htfScore.colorDefToName(htfTeam));
  bz_sendTextMessagef(BZ_SERVER, who,  "  Flag Reset: %s" , DO_FLAG_RESET ? "ENabled":"DISabled");
}

void htfReset(int who)
{
  resetScores();
  bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "*** HTF scores reset by %s", Players[who].callsign);
}

void htfEnable(bool onoff, int who)
{
  char msg[255];
  if (onoff == htfEnabled){
    bz_sendTextMessage(BZ_SERVER, who, "HTF mode is already that way.");
    return;
  }
  htfEnabled = onoff;
  sprintf(msg, "*** HTF mode %s by %s", onoff?"ENabled":"DISabled", Players[who].callsign);
  bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, msg);
}

// handle events
void HTFscore::process(bz_EventData *eventData)
{
  // player JOIN
  if (eventData->eventType == bz_ePlayerJoinEvent) {
    char msg[255];
    bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData;
    bz_debugMessagef(3, "++++++ HTFscore: Player JOINED (ID:%d, TEAM:%d, CALLSIGN:%s)",
		     joinData->playerID, joinData->record->team,
		     joinData->record->callsign.c_str());
    fflush(stdout);
    if (htfTeam!=eNoTeam &&
	joinData->record->team!=htfTeam &&
	joinData->record->team != eObservers) {
      sprintf(msg, "HTF mode enabled, you must join the %s team to play", htfScore.colorDefToName(htfTeam));
      bz_kickUser(joinData->record->playerID, msg, true);
      return;
    }
    if (joinData->record->team == htfTeam)
      listAdd(joinData->playerID, joinData->record->callsign.c_str());

    // player PART
  } else if (eventData->eventType == bz_ePlayerPartEvent) {
    bz_PlayerJoinPartEventData_V1 *joinData = (bz_PlayerJoinPartEventData_V1*)eventData;
    bz_debugMessagef(3, "++++++ HTFscore: Player PARTED (ID:%d, TEAM:%d, CALLSIGN:%s)",
		     joinData->playerID, joinData->record->team,
		     joinData->record->callsign.c_str());
    fflush(stdout);

    if (joinData->record->team == htfTeam)
      listDel (joinData->playerID);

    // flag CAPTURE
  } else if (eventData->eventType == bz_eCaptureEvent) {
    bz_CTFCaptureEventData_V1 *capData = (bz_CTFCaptureEventData_V1*)eventData;
    htfCapture(capData->playerCapping);

    // game START
  } else if (eventData->eventType == bz_eGameStartEvent) {
    bz_GameStartEndEventData_V1 *msgData = (bz_GameStartEndEventData_V1*)eventData;
    bz_debugMessagef(2, "++++++ HTFscore: Game START (%f, %f)",
		     msgData->eventTime, msgData->duration);
    fflush(stdout);
    htfStartGame();

    // game END
  } else if (eventData->eventType == bz_eGameEndEvent) {
    bz_GameStartEndEventData_V1 *msgData = (bz_GameStartEndEventData_V1*)eventData;
    bz_debugMessagef(2, "++++++ HTFscore: Game END (%f, %f)",
		     msgData->eventTime, msgData->duration);
    fflush(stdout);
    htfEndGame();
  }
}

bool checkPerms(int playerID, const char *htfCmd, const char *permName)
{
  if (bz_hasPerm(playerID, permName))
    return true;
  bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "you need \"%s\" permission to do /htf %s",
		      permName, htfCmd);
  return false;
}

// handle /htf command
bool HTFscore::handle(int playerID, bz_ApiString cmd, bz_ApiString, bz_APIStringList* cmdParams)
{
  char subCmd[6];
  if (strcasecmp (cmd.c_str(), "htf"))   // is it for me ?
    return false;
  if (cmdParams->get(0).c_str()[0] == '\0'){
    dispScores(playerID);
    return true;
  }

  strncpy(subCmd, cmdParams->get(0).c_str(), 5);
  subCmd[4] = '\0';
  if (strcasecmp(subCmd, "rese") == 0){
    if (checkPerms(playerID, "reset", "COUNTDOWN"))
      htfReset(playerID);
  } else if (strcasecmp(subCmd, "off") == 0){
    if (checkPerms(playerID, "off", "HTFONOFF"))
      htfEnable(false, playerID);
  } else if (strcasecmp(subCmd, "on") == 0){
    if (checkPerms(playerID, "off", "HTFONOFF"))
      htfEnable(true, playerID);
  } else if (strcasecmp(subCmd, "stat") == 0) {
    htfStats(playerID);
  } else {
    sendHelp(playerID);
  }
  return true;
}

bool commandLineHelp(void){
  const char *help[] = {
    "Command line args:  PLUGINNAME,[TEAM=color]",
    NULL
  };
  bz_debugMessage(0, "+++ HoldTheFlag plugin command-line error");
  for (int x=0; help[x]!=NULL; x++)
    bz_debugMessage(0, help[x]);
  return true;
}

bool parseCommandLine(const char *cmdLine)
{
  if (cmdLine==NULL || *cmdLine=='\0' || strlen(cmdLine) < 5)
    return false;
  htfTeam = eGreenTeam;
  if (strncasecmp(cmdLine, "TEAM=", 5) == 0){
    if ((htfTeam = htfScore.colorNameToDef(cmdLine+5)) == eNoTeam)
      return commandLineHelp();
  } else {
    return commandLineHelp();
  }
  return false;
}

BZF_PLUGIN_CALL int bz_Load(const char* cmdLine)
{
  bz_BasePlayerRecord *playerRecord;

  if (parseCommandLine(cmdLine))
    return -1;

  // get current list of player indices ...
  bz_APIIntList *playerList = bz_newIntList();
  bz_getPlayerIndexList(playerList);
  for (unsigned int i = 0; i < playerList->size(); i++){
    if ((playerRecord = bz_getPlayerByIndex(playerList->get(i))) != NULL){
      listAdd (playerList->get(i), playerRecord->callsign.c_str());
      bz_freePlayerRecord(playerRecord);
    }
  }
  bz_deleteIntList(playerList);

  bz_registerCustomSlashCommand("htf", &htfScore);
  bz_registerEvent(bz_ePlayerJoinEvent, &htfScore);
  bz_registerEvent(bz_ePlayerPartEvent, &htfScore);
  bz_registerEvent(bz_eCaptureEvent, &htfScore);
  bz_registerEvent(bz_eGameStartEvent, &htfScore);
  bz_registerEvent(bz_eGameEndEvent, &htfScore);
  bz_debugMessagef(1, "HoldTheFlag plugin loaded - v%s", HOLDTHEFLAG_VER);
  return 0;
}

BZF_PLUGIN_CALL int bz_Unload(void)
{
  bz_removeCustomSlashCommand("htf");
  bz_removeEvent(bz_ePlayerJoinEvent, &htfScore);
  bz_removeEvent(bz_ePlayerPartEvent, &htfScore);
  bz_removeEvent(bz_eCaptureEvent, &htfScore);
  bz_removeEvent(bz_eGameStartEvent, &htfScore);
  bz_removeEvent(bz_eGameEndEvent, &htfScore);
  bz_debugMessage(1, "HoldTheFlag plugin unloaded");
  return 0;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Georgia Institute of Technology
 *
 * 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.
 */

/**
 * @file    clear_cache.cpp
 * @ingroup
 * @author  tpan
 * @brief   clears cache on a linux system
 * @details for use before doing file io benchmark.
 *
 * Copyright (c) 2016 Georgia Institute of Technology.  All Rights Reserved.
 *
 * TODO add License
 */

#include "utils/memory_usage.hpp"

/**
 * @brief  clear the disk cache in linux by allocating a bunch of memory.
 * @details  in 1MB chunks to workaround memory fragmentation preventing allocation.
 *           can potentially use swap, or if there is not enough physical + swap, be killed.
 *
 */
void clear_cache() {
  size_t avail = MemUsage::get_usable_mem();
  size_t rem = avail;

  size_t minchunk = 1UL << 24;    // 16MB chunks
  size_t chunk = minchunk;

  size_t maxchunk = std::min(1UL << 30, (avail >> 4));
  for ( ;chunk < maxchunk; chunk <<= 1) ;   // keep increasing chunks until larger than 1/16 of avail, or until 1GB.

  std::vector<size_t *> dummy;

  size_t nchunks;
  size_t i;
  size_t *ptr;
  size_t j = 0;

  printf("begin clearing %lu bytes\n", avail);
  size_t iter_cleared = 0;

  while ((chunk >= minchunk) && (rem > minchunk)) {
    nchunks = rem / chunk;
    iter_cleared = 0;

    for (i = 0; i < nchunks; ++i, ++j) {
//      if ((j % 16) == 0) {
//        printf("%lu ", j);  // 16 outputs.
//        fflush(stdout);
//      }

      // (c|m)alloc/free seems to be optimized out.  using new works.
      ptr = new size_t[(chunk / sizeof(size_t))];

      iter_cleared += chunk;
      memset(ptr, 0, chunk);
      ptr[0] = i;

      dummy.push_back(ptr);
    }

    //    // check for available memory, every 64 MBs
    //    if ((i % 64) == 0) {
    //      avail = MemUsage::get_usable_mem();
    //      if (avail < (64 << 20)) break;   // less than 64MB available.
    //    }
    rem -= iter_cleared;

    printf("cleared %lu bytes using %lu chunk %lu bytes. total cleared %lu bytes, rem %lu bytes \n", iter_cleared, i, chunk, avail - rem, rem);
    fflush(stdout);

    // reduce the size of the chunk by 4
    chunk >>= 2;

  }
  printf("finished clearing %lu/%lu bytes with %lu remaining\n", avail - rem, avail, rem);
  fflush(stdout);

  size_t sum = 0;
  size_t ii = 0;
  for (; ii < dummy.size(); ++ii) {
    ptr = dummy[ii];

    if (ptr != nullptr) {
//      if ((ii % 16) == 0) {
//        printf("%lu ", ii);  // 16 outputs.
//        fflush(stdout);
//      }
      sum += ptr[ii >> 10];
      delete [] ptr;
      //free(ptr);
      dummy[ii] = nullptr;
    } else {
      break;
    }
  }
  printf("\n");
  printf("disk cache cleared (dummy %lu). %lu blocks %lu bytes\n", sum, j, avail - rem);
}

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

  clear_cache();

  return 0;
}
<commit_msg>WIP: further testing on large memory machine<commit_after>/*
 * Copyright 2015 Georgia Institute of Technology
 *
 * 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.
 */

/**
 * @file    clear_cache.cpp
 * @ingroup
 * @author  tpan
 * @brief   clears cache on a linux system
 * @details for use before doing file io benchmark.
 *
 * Copyright (c) 2016 Georgia Institute of Technology.  All Rights Reserved.
 *
 * TODO add License
 */

#include "utils/memory_usage.hpp"

#ifdef USE_OPENMP
#include <omp.h>
#endif

/**
 * @brief  clear the disk cache in linux by allocating a bunch of memory.
 * @details  in 1MB chunks to workaround memory fragmentation preventing allocation.
 *           can potentially use swap, or if there is not enough physical + swap, be killed.
 *
 */
void clear_cache() {
  size_t avail = MemUsage::get_usable_mem();
  size_t rem = avail;

  size_t minchunk = 1UL << 24;    // 16MB chunks
  size_t chunk = minchunk;

  size_t maxchunk = std::min(1UL << 30, (avail >> 4));
  for ( ;chunk < maxchunk; chunk <<= 1) ;   // keep increasing chunks until larger than 1/16 of avail, or until 1GB.

  std::vector<size_t *> dummy;

  size_t nchunks;
  size_t j = 0, lj;

  printf("begin clearing %lu bytes\n", avail);
  size_t iter_cleared = 0;

  while ((chunk >= minchunk) && (rem > minchunk)) {
    nchunks = rem / chunk;

    iter_cleared = 0;
    lj = 0;
#pragma omp parallel for shared(nchunks, chunk, dummy) reduction(+:lj, iter_cleared)
    for (size_t i = 0; i < nchunks; ++i) {

      // (c|m)alloc/free seems to be optimized out.  using new works.
      size_t * ptr = new size_t[(chunk / sizeof(size_t))];

      iter_cleared += chunk;
      memset(ptr, 0, chunk);
      ptr[0] = i;

#pragma omp critical
      {
        dummy.push_back(ptr);
      }

      ++lj;
    }

    j += lj;

    //    // check for available memory, every 64 MBs
    //    if ((i % 64) == 0) {
    //      avail = MemUsage::get_usable_mem();
    //      if (avail < (64 << 20)) break;   // less than 64MB available.
    //    }
    rem -= iter_cleared;

    printf("cleared %lu bytes using %lu chunk %lu bytes. total cleared %lu bytes, rem %lu bytes \n", iter_cleared, nchunks, chunk, avail - rem, rem);
    fflush(stdout);

    // reduce the size of the chunk by 4
    chunk >>= 2;

  }
  printf("finished clearing %lu/%lu bytes with %lu remaining\n", avail - rem, avail, rem);
  fflush(stdout);

  size_t sum = 0;
  size_t ii = 0;
  size_t *ptr;
  for (; ii < dummy.size(); ++ii) {
    ptr = dummy[ii];

    if (ptr != nullptr) {
//      if ((ii % 16) == 0) {
//        printf("%lu ", ii);  // 16 outputs.
//        fflush(stdout);
//      }
      sum += ptr[ii >> 10];
      delete [] ptr;
      //free(ptr);
      dummy[ii] = nullptr;
    } else {
      break;
    }
  }
  printf("\n");
  printf("disk cache cleared (dummy %lu). %lu blocks %lu bytes\n", sum, j, avail - rem);
}

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

  clear_cache();

  return 0;
}
<|endoftext|>


<commit_before>// The "Square Detector" program.
// It loads several images sequentially and tries to find squares in
// each image

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <math.h>
#include <string.h>
#include <stdio.h>

#include <ros/ros.h>
#include <osuar_vision/windowCoordinates.h>

using namespace cv;

int thresh = 50, N = 11;

// Threshold for maximum cosine between angles (x100).
int maxCosineThresh = 20;

// Threshold for ratio of shortest side / longest side (x100).
int sideRatioThresh = 75;

// Maximum square area.
int maxSquareArea = 41000;

// Find colors of any hue...
int wallHueLow  = 50;
int wallHueHigh = 132;

// ...of low saturation...
int wallSatLow  = 0;
int wallSatHigh = 100;

// ...ranging down to gray, but not completely dark. That is to say, white.
int wallValLow  = 90;
int wallValHigh = 255;

ros::Publisher visPub;
osuar_vision::windowCoordinates winCoords;

// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
static double angle( Point pt1, Point pt2, Point pt0 )
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
static void findSquares( const Mat& image, vector<vector<Point> >& squares )
{
    squares.clear();

    Mat pyr, timg, gray0(image.size(), CV_8U), gray;

    // down-scale and upscale the image to filter out the noise
    pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
    pyrUp(pyr, timg, image.size());
    vector<vector<Point> > contours;

    // find squares in every color plane of the image
    //for( int c = 0; c < 3; c++ )
    //{
        //int ch[] = {c, 0};
        //mixChannels(&timg, 1, &gray0, 1, ch, 1);

        // try several threshold levels
        for( int l = 0; l < N; l++ )
        {
            // hack: use Canny instead of zero threshold level.
            // Canny helps to catch squares with gradient shading
            if( l == 0 )
            {
                // apply Canny. Take the upper threshold from slider
                // and set the lower to 0 (which forces edges merging)
                Canny(image, gray, 0, thresh, 5);
                // dilate canny output to remove potential
                // holes between edge segments
                dilate(gray, gray, Mat(), Point(-1,-1));
            }
            else
            {
                // apply threshold if l!=0:
                //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
                gray = image >= (l+1)*255/N;
            }

            // find contours and store them all as a list
            findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

            vector<Point> approx;

            // test each contour
            for( size_t i = 0; i < contours.size(); i++ )
            {
                // approximate contour with accuracy proportional
                // to the contour perimeter
                approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

                // square contours should have 4 vertices after approximation
                // relatively large area (to filter out noisy contours)
                // and be convex.
                // Note: absolute value of an area is used because
                // area may be positive or negative - in accordance with the
                // contour orientation
                if( approx.size() == 4 &&
                    fabs(contourArea(Mat(approx))) > 1000 &&
                    fabs(contourArea(Mat(approx))) < maxSquareArea &&
                    isContourConvex(Mat(approx)) )
                {
                    double maxCosine = 0;
                    double minSideLen = 100000;
                    double maxSideLen = 0;
                    double sideRatio = 0;

                    for( int j = 2; j < 5; j++ )
                    {
                        // find the maximum cosine of the angle between joint edges
                        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                        maxCosine = MAX(maxCosine, cosine);

                        // Find the maximum difference in length of adjacent
                        // sides
                        double sideLen = sqrt(pow((approx[j%4].x - approx[(j+1)%4].x), 2) + pow((approx[j%4].y - approx[(j+1)%4].y), 2));
                        minSideLen = MIN(minSideLen, sideLen);
                        maxSideLen = MAX(maxSideLen, sideLen);
                    }

                    sideRatio = minSideLen / maxSideLen;

                    std::cout << minSideLen << "  " << maxSideLen << "\n";

                    // if cosines of all angles are small
                    // (all angles are ~90 degree) then write quandrange
                    // vertices to resultant sequence
                    if( maxCosine < ((double) maxCosineThresh)/100 && sideRatio >= (double) sideRatioThresh/100 )
                        squares.push_back(approx);
                }
            }
        }
    //}
}

// the function draws all the squares in the image
static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
{
    for( size_t i = 0; i < squares.size(); i++ )
    {
        const Point* p = &squares[i][0];
        int n = (int)squares[i].size();
        polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);

        std::cout << "x: " << squares[i][0].x << "  y: " << squares[i][0].y << "\n";

        // Only publish coordinates for one of the squares. Coordinates are
        // shifted over by half the camera resolution (which itself is scaled
        // down by a factor of two!) on each axis. The y coordinate is inverted
        // so up is positive.
        if (i == 0) {
            putText(image, "0", squares[0][0], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "1", squares[0][1], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "2", squares[0][2], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "3", squares[0][3], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            winCoords.x =   (squares[0][0].x + squares[0][2].x)/2 - 180;
            winCoords.y = -((squares[0][0].y + squares[0][2].y)/2 - 120);
            winCoords.size = fabs(squares[0][0].x - squares[0][2].x);
            visPub.publish(winCoords);
        }
    }
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "vision");
    ros::NodeHandle nh;
    visPub = nh.advertise<osuar_vision::windowCoordinates>("window_coordinates", 1);

    // Instantiate VideoCapture object. See here for details:
    // http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html
    VideoCapture cap(1);

    // Configure video. Our camera NEEDS the frame width to be set to 720
    // pixels.
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 720);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
    //cap.set(CV_CAP_PROP_FPS, 20);

    // Instantiate a Mat in which to store each video frame.
    Mat origFrame;
    Mat resizedFrame;   // Scaled-down from origFrame by factor of 2.
    Mat hsvFrame;   // Converted to HSV space from resizedFrame.
    Mat bwFrame;   // Black/white image after thresholding hsvFrame.

    cvNamedWindow("control panel", 1);
    cvMoveWindow("control panel", 450, 20);

    cvNamedWindow("origImage", 1);
    cvMoveWindow("origImage", 20, 20);

    cvNamedWindow("bwImage", 1);
    cvMoveWindow("bwImage", 20, 270);

    cvCreateTrackbar("threshold",   "control panel", &thresh,      300, NULL);
    cvCreateTrackbar("maxCosineThresh (x100)", "control panel", &maxCosineThresh, 100, NULL);
    cvCreateTrackbar("sideRatioThresh (x100)", "control panel", &sideRatioThresh, 100, NULL);
    cvCreateTrackbar("maxSquareArea", "control panel", &maxSquareArea, 100000, NULL);
    cvCreateTrackbar("wallHueLow",  "control panel", &wallHueLow,  179, NULL);
    cvCreateTrackbar("wallHueHigh", "control panel", &wallHueHigh, 179, NULL);
    cvCreateTrackbar("wallSatLow",  "control panel", &wallSatLow,  255, NULL);
    cvCreateTrackbar("wallSatHigh", "control panel", &wallSatHigh, 255, NULL);
    cvCreateTrackbar("wallValLow",  "control panel", &wallValLow,  255, NULL);
    cvCreateTrackbar("wallValHigh", "control panel", &wallValHigh, 255, NULL);
    vector<vector<Point> > squares;

    while (true) {
        // Capture image.
        cap >> origFrame;

        // Resize the image to increase processing rate. See here for details:
        // http://opencv.willowgarage.com/documentation/cpp/image_filtering.html
        pyrDown(origFrame, resizedFrame, Size(origFrame.cols/2, origFrame.rows/2));

        // Convert the frame to HSV. TODO: combine this with more filtering and
        // turn into function.
        cvtColor(resizedFrame, hsvFrame, CV_BGR2HSV);

        // Threshold hsvFrame for color of maze walls.
        inRange(hsvFrame, Scalar(wallHueLow,  wallSatLow,  wallValLow),
                          Scalar(wallHueHigh, wallSatHigh, wallValHigh), bwFrame);

        // Find and draw squares.
        findSquares(bwFrame, squares);
        drawSquares(resizedFrame, squares);

        // Show the image, with the squares overlaid.
        imshow("origImage", resizedFrame);
        imshow("bwImage", bwFrame);

        // Wait 5 milliseconds for a keypress.
        int c = waitKey(5);
        // Exit if the spacebar is pressed. NOTE: killing the program with
        // Ctrl+C sometimes stops OpenCV at a bad place and effects a kernel
        // panic! If you really like Ctrl+C, do so at your own risk!
        if ((char) c == 32) {
            return 0;
        }
    }

    return 0;
}
<commit_msg>Move Mat instantiation to beginning of file.<commit_after>// The "Square Detector" program.
// It loads several images sequentially and tries to find squares in
// each image

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <math.h>
#include <string.h>
#include <stdio.h>

#include <ros/ros.h>
#include <osuar_vision/windowCoordinates.h>

using namespace cv;

int thresh = 50, N = 11;

// Threshold for maximum cosine between angles (x100).
int maxCosineThresh = 20;

// Threshold for ratio of shortest side / longest side (x100).
int sideRatioThresh = 75;

// Maximum square area.
int maxSquareArea = 41000;

// Find colors of any hue...
int wallHueLow  = 0;
int wallHueHigh = 179;

// ...of low saturation...
int wallSatLow  = 0;
int wallSatHigh = 50;

// ...ranging down to gray, but not completely dark. That is to say, white.
int wallValLow  = 90;
int wallValHigh = 255;

// Hough transform thresholds
int minLineLen = 5;
int maxLineGap = 10;

// Instantiate a Mat in which to store each video frame.
Mat origFrame;
Mat resizedFrame;   // Scaled-down from origFrame by factor of 2.
Mat hsvFrame;   // Converted to HSV space from resizedFrame.
Mat bwFrame;   // Black/white image after thresholding hsvFrame.
Mat grayFrame;
Mat cannyFrame;

ros::Publisher visPub;
osuar_vision::windowCoordinates winCoords;

// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
static double angle( Point pt1, Point pt2, Point pt0 )
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
static void findSquares( const Mat& image, vector<vector<Point> >& squares )
{
    squares.clear();

    Mat pyr, timg;

    // down-scale and upscale the image to filter out the noise
    pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
    pyrUp(pyr, timg, image.size());
    vector<vector<Point> > contours;

    // find squares in every color plane of the image
    //for( int c = 0; c < 3; c++ )
    //{
        //int ch[] = {c, 0};
        //mixChannels(&timg, 1, &gray0, 1, ch, 1);

        // try several threshold levels
        for( int l = 0; l < N; l++ )
        {
            // hack: use Canny instead of zero threshold level.
            // Canny helps to catch squares with gradient shading
            if( l == 0 )
            {
                // apply Canny. Take the upper threshold from slider
                // and set the lower to 0 (which forces edges merging)
                Canny(image, gray, 0, thresh, 5);
                // dilate canny output to remove potential
                // holes between edge segments
                dilate(gray, gray, Mat(), Point(-1,-1));
            }
            else
            {
                // apply threshold if l!=0:
                //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
                gray = image >= (l+1)*255/N;
            }

            // find contours and store them all as a list
            findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

            vector<Point> approx;

            // test each contour
            for( size_t i = 0; i < contours.size(); i++ )
            {
                // approximate contour with accuracy proportional
                // to the contour perimeter
                approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

                // square contours should have 4 vertices after approximation
                // relatively large area (to filter out noisy contours)
                // and be convex.
                // Note: absolute value of an area is used because
                // area may be positive or negative - in accordance with the
                // contour orientation
                if( approx.size() == 4 &&
                    fabs(contourArea(Mat(approx))) > 1000 &&
                    fabs(contourArea(Mat(approx))) < maxSquareArea &&
                    isContourConvex(Mat(approx)) )
                {
                    double maxCosine = 0;
                    double minSideLen = 100000;
                    double maxSideLen = 0;
                    double sideRatio = 0;

                    for( int j = 2; j < 5; j++ )
                    {
                        // find the maximum cosine of the angle between joint edges
                        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                        maxCosine = MAX(maxCosine, cosine);

                        // Find the maximum difference in length of adjacent
                        // sides
                        double sideLen = sqrt(pow((approx[j%4].x - approx[(j+1)%4].x), 2) + pow((approx[j%4].y - approx[(j+1)%4].y), 2));
                        minSideLen = MIN(minSideLen, sideLen);
                        maxSideLen = MAX(maxSideLen, sideLen);
                    }

                    sideRatio = minSideLen / maxSideLen;

                    std::cout << minSideLen << "  " << maxSideLen << "\n";

                    // if cosines of all angles are small
                    // (all angles are ~90 degree) then write quandrange
                    // vertices to resultant sequence
                    if( maxCosine < ((double) maxCosineThresh)/100 && sideRatio >= (double) sideRatioThresh/100 )
                        squares.push_back(approx);
                }
            }
        }
    //}
}

// the function draws all the squares in the image
static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
{
    for( size_t i = 0; i < squares.size(); i++ )
    {
        const Point* p = &squares[i][0];
        int n = (int)squares[i].size();
        polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);

        std::cout << "x: " << squares[i][0].x << "  y: " << squares[i][0].y << "\n";

        // Only publish coordinates for one of the squares. Coordinates are
        // shifted over by half the camera resolution (which itself is scaled
        // down by a factor of two!) on each axis. The y coordinate is inverted
        // so up is positive.
        if (i == 0) {
            putText(image, "0", squares[0][0], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "1", squares[0][1], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "2", squares[0][2], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            putText(image, "3", squares[0][3], FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255,0,0));
            winCoords.x =   (squares[0][0].x + squares[0][2].x)/2 - 180;
            winCoords.y = -((squares[0][0].y + squares[0][2].y)/2 - 120);
            winCoords.size = fabs(squares[0][0].x - squares[0][2].x);
            visPub.publish(winCoords);
        }
    }
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "vision");
    ros::NodeHandle nh;
    visPub = nh.advertise<osuar_vision::windowCoordinates>("window_coordinates", 1);

    // Instantiate VideoCapture object. See here for details:
    // http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html
    VideoCapture cap(1);

    // Configure video. Our camera NEEDS the frame width to be set to 720
    // pixels.
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 720);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
    //cap.set(CV_CAP_PROP_FPS, 20);

    cvNamedWindow("control panel", 1);
    cvMoveWindow("control panel", 450, 20);

    cvNamedWindow("origImage", 1);
    cvMoveWindow("origImage", 20, 20);

    cvNamedWindow("bwImage", 1);
    cvMoveWindow("bwImage", 20, 270);

    cvCreateTrackbar("threshold",   "control panel", &thresh,      300, NULL);
    cvCreateTrackbar("maxCosineThresh (x100)", "control panel", &maxCosineThresh, 100, NULL);
    cvCreateTrackbar("sideRatioThresh (x100)", "control panel", &sideRatioThresh, 100, NULL);
    cvCreateTrackbar("maxSquareArea", "control panel", &maxSquareArea, 100000, NULL);
    cvCreateTrackbar("wallHueLow",  "control panel", &wallHueLow,  179, NULL);
    cvCreateTrackbar("wallHueHigh", "control panel", &wallHueHigh, 179, NULL);
    cvCreateTrackbar("wallSatLow",  "control panel", &wallSatLow,  255, NULL);
    cvCreateTrackbar("wallSatHigh", "control panel", &wallSatHigh, 255, NULL);
    cvCreateTrackbar("wallValLow",  "control panel", &wallValLow,  255, NULL);
    cvCreateTrackbar("wallValHigh", "control panel", &wallValHigh, 255, NULL);
    vector<vector<Point> > squares;

    while (true) {
        // Capture image.
        cap >> origFrame;

        // Resize the image to increase processing rate. See here for details:
        // http://opencv.willowgarage.com/documentation/cpp/image_filtering.html
        pyrDown(origFrame, resizedFrame, Size(origFrame.cols/2, origFrame.rows/2));

        // Convert the frame to HSV. TODO: combine this with more filtering and
        // turn into function.
        cvtColor(resizedFrame, hsvFrame, CV_BGR2HSV);

        // Threshold hsvFrame for color of maze walls.
        inRange(hsvFrame, Scalar(wallHueLow,  wallSatLow,  wallValLow),
                          Scalar(wallHueHigh, wallSatHigh, wallValHigh), bwFrame);

        // Find and draw squares.
        findSquares(bwFrame, squares);
        drawSquares(resizedFrame, squares);

        // Show the image, with the squares overlaid.
        imshow("origImage", resizedFrame);
        imshow("bwImage", bwFrame);

        // Wait 5 milliseconds for a keypress.
        int c = waitKey(5);
        // Exit if the spacebar is pressed. NOTE: killing the program with
        // Ctrl+C sometimes stops OpenCV at a bad place and effects a kernel
        // panic! If you really like Ctrl+C, do so at your own risk!
        if ((char) c == 32) {
            return 0;
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>/* Author: Nicholas Nell
   email: nicholas.nell@colorado.edu

   Sampling thread for the NI PCI-DIO-32HS and PCI-6601 that act as
   NSROC telemtery.
*/

#include <QDebug>
#include <regex.h>

#include "nidaqplugin.h"

NIDAQPlugin::NIDAQPlugin() : SamplingThreadPlugin() {
    FILE *fp;
    char line_buffer[255];
    uint32_t line_number = 0;
    int err = 0;

    regex_t daq_card_reg;
    regex_t timer_card_reg;

    regmatch_t daq_match[2];
    regmatch_t timer_match[2];

    unsigned int chanlist[COM_N_CHAN];

    qDebug() << "NIDAQ Init Starting...";

    if (regcomp(&daq_card_reg, DAQ_PATTERN, 0)) {
        qDebug() << "DAQ regcomp fail";
        throw;
    }

    if (regcomp(&timer_card_reg, TIMER_PATTERN, 0)) {
        qDebug() << "DAQ regcomp fail";
        throw;
    }

    fp = fopen(COM_PROC, "r");
    if (fp == NULL) {
        qDebug() << "Can't open " << COM_PROC;
        throw;
    }

    /* Find comedi device file names... */
    while (fgets(line_buffer, sizeof(line_buffer), fp)) {
        ++line_number;
        if (!regexec(&daq_card_reg, line_buffer, 2, daq_match, 0)) {
            daq_dev_file = (char *)malloc(strlen(COM_PREFIX) + 2);
            sprintf(daq_dev_file,
                    "%s%.*s",
                    COM_PREFIX,
                    daq_match[1].rm_eo - daq_match[1].rm_so,
                    &line_buffer[daq_match[1].rm_so]);
            qDebug() << "DIO dev file: " << daq_dev_file;
        }

        if (!regexec(&timer_card_reg, line_buffer, 2, timer_match, 0)) {
            timer_dev_file = (char *)malloc(strlen(COM_PREFIX) + 2);
            sprintf(timer_dev_file,
                    "%s%.*s",
                    COM_PREFIX,
                    timer_match[1].rm_eo - timer_match[1].rm_so,
                    &line_buffer[timer_match[1].rm_so]);
            qDebug() << "TIMER dev file: " << timer_dev_file;
        }

    }

    regfree(&daq_card_reg);
    regfree(&timer_card_reg);

    /* open dio device */
    dio_dev = comedi_open(daq_dev_file);
    if (dio_dev == NULL) {
        qDebug() << "Error opening dio dev file: " << daq_dev_file;
        throw;
    }

    /* lock the DIO device (dubdev 0) */
    err = comedi_lock(dio_dev, 0);
    if (err < 0) {
        qDebug() << "Error locking comedi device, subdevice: " << daq_dev_file << 0;
        throw;
    }

    timer_dev = comedi_open(timer_dev_file);
    if (timer_dev == NULL) {
        qDebug() << "Error opening timer dev file: " << timer_dev_file;
        throw;
    }

    /* lock the timer device (dubdev 2) */
    err = comedi_lock(timer_dev, 2);
    if (err < 0) {
        qDebug() << "Error locking comedi device, subdevice: " << timer_dev_file << 2;
        throw;
    }

    /* Don't start pulse train until we acquire */
    if (ni_gpct_stop_pulse_gen(timer_dev, 2) != 0) {
        qDebug() << "Unable to stop pulse train...";
        throw;
    }

    /* Set device file params */
    fcntl(comedi_fileno(dio_dev), F_SETFL, O_NONBLOCK);

    memset(&cmd, 0, sizeof(cmd));

    /* This command is legit for the PCI-DIO-32HS */
    cmd.subdev         = 0;
    cmd.flags          = 0;
    cmd.start_src      = TRIG_NOW;
    cmd.start_arg      = 0;
    cmd.scan_begin_src = TRIG_EXT;
    cmd.scan_begin_arg = CR_INVERT; /* Read on the trailing edge */
    cmd.convert_src    = TRIG_NOW;
    cmd.convert_arg    = 0;
    cmd.scan_end_src   = TRIG_COUNT;
    cmd.scan_end_arg   = COM_N_CHAN;
    cmd.stop_src       = TRIG_NONE;
    cmd.stop_arg       = 0;

    cmd.chanlist = chanlist;
    cmd.chanlist_len = COM_N_CHAN;

    /* Prep all channels */
    for (int i = 0; i < COM_N_CHAN; i++) {
        /* Note range is 0 (we are digital!) */
        chanlist[i] = CR_PACK(0, 0, AREF_GROUND);
    }

    /* Test the command */
    err = comedi_command_test(dio_dev, &cmd);
    if (err != 0) {
        qDebug() << "comedi command failed test.";
        qDebug() << "comedi_command_test result: " <<  err;
        int blah = comedi_get_version_code(dio_dev);
        qDebug() <<
            "COMEDI VER: " <<
            (0x0000ff & (blah >> 16)) <<
            "." << (0x0000ff & (blah >> 8)) <<
            "." << (0x0000ff & blah);

        throw;
    }

    err = comedi_dio_config(timer_dev, 1, 36, COMEDI_OUTPUT);
    if (err != 0) {
        qDebug() << "Failed to set timer to output. Error #: " << err;
        throw;
    }

    abort = false;
    pauseSampling = false;
    _pc = new MDDASPlotConfig();
    _pc->setXMax(8192);
    _pc->setXMin(0);
    _pc->setYMax(8192);
    _pc->setYMin(0);
    _pc->setPMax(256);
    _pc->setPMin(0);

    if (fclose(fp)) {
        qDebug() << "Error closing " << COM_PROC;
        throw;
    }

    qDebug() << "NIDAQ Init complete...";
}

/* close thread */
NIDAQPlugin::~NIDAQPlugin() {
    ni_gpct_stop_pulse_gen(timer_dev, 2);
    /* stop command */
    comedi_cancel(dio_dev, 0);

    comedi_close(dio_dev);
    comedi_close(timer_dev);

    free(daq_dev_file);
    free(timer_dev_file);
}

void NIDAQPlugin::run() {
    int i = 0;
    int j = 0;
    int num_photons = 0;

    QMutex sleepM;
    QVector<MDDASDataPoint> v;
    sleepM.lock();

    forever {
        mutex.lock();
        if (pauseSampling) {
            condition.wait(&mutex);
        }
        mutex.unlock();

        if (abort) {
            qDebug() << "called abort!" << QThread::currentThread();
            return;
        }

        //qDebug() << "nidaq!";

        condition.wait(&sleepM, 1);

        //qDebug() << "blip" << QThread::currentThread();
        //sleep();
        /* Use a wait condition instead of sleep() so that the thread
           can be awoken. */
        //condition.wait(&sleepM, 100);

    }
}

int NIDAQPlugin::ni_gpct_start_pulse_gen(comedi_t *device,
                                         unsigned subdevice,
                                         unsigned period_ns,
                                         unsigned up_time_ns) {
    int retval;
    lsampl_t counter_mode;
    const unsigned clock_period_ns = 50; /* 20MHz clock */
    unsigned up_ticks, down_ticks;

    retval = comedi_reset(device, subdevice);
    if (retval < 0) return retval;

    retval = comedi_set_gate_source(device,
                                    subdevice,
                                    0,
                                    0,
                                    NI_GPCT_DISABLED_GATE_SELECT | CR_EDGE);
    if (retval < 0) return retval;
    retval = comedi_set_gate_source(device,
                                    subdevice,
                                    0,
                                    1,
                                    NI_GPCT_DISABLED_GATE_SELECT | CR_EDGE);
    if (retval < 0) {
        //fprintf(stderr, "Failed to set second gate source.  This is expected for older boards (e-series, etc.)\n"
        //        "that don't have a second gate.\n");
        qDebug() << "Failed to set second gate source.  This is expected for older boards (e-series, etc.)";
        qDebug() << "that don't have a second gate.";

    }

    counter_mode = NI_GPCT_COUNTING_MODE_NORMAL_BITS;
    /* toggle output on terminal count */
    counter_mode |= NI_GPCT_OUTPUT_TC_TOGGLE_BITS;
    /* load on terminal count */
    counter_mode |= NI_GPCT_LOADING_ON_TC_BIT;
    /* alternate the reload source between the load a and load b registers */
    counter_mode |= NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS;
    /* count down */
    counter_mode |= NI_GPCT_COUNTING_DIRECTION_DOWN_BITS;
    /* initialize load source as load b register */
    counter_mode |= NI_GPCT_LOAD_B_SELECT_BIT;
    /* don't stop on terminal count */
    counter_mode |= NI_GPCT_STOP_ON_GATE_BITS;
    /* don't disarm on terminal count or gate signal */
    counter_mode |= NI_GPCT_NO_HARDWARE_DISARM_BITS;
    retval = comedi_set_counter_mode(device, subdevice, 0, counter_mode);
    if (retval < 0) return retval;

    /* 20MHz clock */
    retval = comedi_set_clock_source(device,
                                     subdevice,
                                     0,
                                     NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS,
                                     clock_period_ns);
    if (retval < 0) return retval;

    up_ticks = (up_time_ns + clock_period_ns / 2) / clock_period_ns;
    down_ticks = (period_ns + clock_period_ns / 2) / clock_period_ns - up_ticks;
    /* set initial counter value by writing to channel 0 */
    retval = comedi_data_write(device, subdevice, 0, 0, 0, down_ticks);
    if (retval < 0) return retval;
    /* set "load a" register to the number of clock ticks the counter
       output should remain low by writing to channel 1. */
    comedi_data_write(device, subdevice, 1, 0, 0, down_ticks);
    if (retval < 0) return retval;
    /* set "load b" register to the number of clock ticks the counter
       output should remain high by writing to channel 2 */
    comedi_data_write(device, subdevice, 2, 0, 0, up_ticks);
    if(retval < 0) return retval;

    retval = comedi_arm(device, subdevice, NI_GPCT_ARM_IMMEDIATE);
    if (retval < 0) return retval;

    return 0;
}

int NIDAQPlugin::ni_gpct_stop_pulse_gen(comedi_t *device, unsigned subdevice) {
    comedi_insn insn;
    lsampl_t data;

    memset(&insn, 0, sizeof(comedi_insn));
    insn.insn = INSN_CONFIG;
    insn.subdev = subdevice;
    insn.chanspec = 0;
    insn.data = &data;
    insn.n = 1;
    data = INSN_CONFIG_DISARM;

    if (comedi_do_insn(device, &insn) >= 0) {
        return 0;
    } else {
        return -1;
    }
}

Q_EXPORT_PLUGIN2(nidaqplugin, NIDAQPlugin);

<commit_msg>Very basic niplugin acquisition with timer start/pause<commit_after>/* Author: Nicholas Nell
   email: nicholas.nell@colorado.edu

   Sampling thread for the NI PCI-DIO-32HS and PCI-6601 that act as
   NSROC telemtery.
*/

#include <QDebug>
#include <regex.h>
#include <unistd.h>

#include "nidaqplugin.h"

NIDAQPlugin::NIDAQPlugin() : SamplingThreadPlugin() {
    FILE *fp;
    char line_buffer[255];
    uint32_t line_number = 0;
    int err = 0;

    regex_t daq_card_reg;
    regex_t timer_card_reg;

    regmatch_t daq_match[2];
    regmatch_t timer_match[2];

    unsigned int chanlist[COM_N_CHAN];

    qDebug() << "NIDAQ Init Starting...";

    if (regcomp(&daq_card_reg, DAQ_PATTERN, 0)) {
        qDebug() << "DAQ regcomp fail";
        throw;
    }

    if (regcomp(&timer_card_reg, TIMER_PATTERN, 0)) {
        qDebug() << "DAQ regcomp fail";
        throw;
    }

    fp = fopen(COM_PROC, "r");
    if (fp == NULL) {
        qDebug() << "Can't open " << COM_PROC;
        throw;
    }

    /* Find comedi device file names... */
    while (fgets(line_buffer, sizeof(line_buffer), fp)) {
        ++line_number;
        if (!regexec(&daq_card_reg, line_buffer, 2, daq_match, 0)) {
            daq_dev_file = (char *)malloc(strlen(COM_PREFIX) + 2);
            sprintf(daq_dev_file,
                    "%s%.*s",
                    COM_PREFIX,
                    daq_match[1].rm_eo - daq_match[1].rm_so,
                    &line_buffer[daq_match[1].rm_so]);
            qDebug() << "DIO dev file: " << daq_dev_file;
        }

        if (!regexec(&timer_card_reg, line_buffer, 2, timer_match, 0)) {
            timer_dev_file = (char *)malloc(strlen(COM_PREFIX) + 2);
            sprintf(timer_dev_file,
                    "%s%.*s",
                    COM_PREFIX,
                    timer_match[1].rm_eo - timer_match[1].rm_so,
                    &line_buffer[timer_match[1].rm_so]);
            qDebug() << "TIMER dev file: " << timer_dev_file;
        }

    }

    regfree(&daq_card_reg);
    regfree(&timer_card_reg);

    /* open dio device */
    dio_dev = comedi_open(daq_dev_file);
    if (dio_dev == NULL) {
        qDebug() << "Error opening dio dev file: " << daq_dev_file;
        throw;
    }

    /* lock the DIO device (dubdev 0) */
    err = comedi_lock(dio_dev, 0);
    if (err < 0) {
        qDebug() << "Error locking comedi device, subdevice: " << daq_dev_file << 0;
        throw;
    }

    timer_dev = comedi_open(timer_dev_file);
    if (timer_dev == NULL) {
        qDebug() << "Error opening timer dev file: " << timer_dev_file;
        throw;
    }

    /* lock the timer device (dubdev 2) */
    err = comedi_lock(timer_dev, 2);
    if (err < 0) {
        qDebug() << "Error locking comedi device, subdevice: " << timer_dev_file << 2;
        throw;
    }

    /* Don't start pulse train until we acquire */
    if (ni_gpct_stop_pulse_gen(timer_dev, 2) != 0) {
        qDebug() << "Unable to stop pulse train...";
        throw;
    }

    /* Set device file params */
    fcntl(comedi_fileno(dio_dev), F_SETFL, O_NONBLOCK);

    memset(&cmd, 0, sizeof(cmd));

    /* This command is legit for the PCI-DIO-32HS */
    cmd.subdev         = 0;
    cmd.flags          = 0;
    cmd.start_src      = TRIG_NOW;
    cmd.start_arg      = 0;
    cmd.scan_begin_src = TRIG_EXT;
    cmd.scan_begin_arg = CR_INVERT; /* Read on the trailing edge */
    cmd.convert_src    = TRIG_NOW;
    cmd.convert_arg    = 0;
    cmd.scan_end_src   = TRIG_COUNT;
    cmd.scan_end_arg   = COM_N_CHAN;
    cmd.stop_src       = TRIG_NONE;
    cmd.stop_arg       = 0;

    cmd.chanlist = chanlist;
    cmd.chanlist_len = COM_N_CHAN;

    /* Prep all channels */
    for (int i = 0; i < COM_N_CHAN; i++) {
        /* Note range is 0 (we are digital!) */
        chanlist[i] = CR_PACK(0, 0, AREF_GROUND);
    }

    /* Test the command */
    err = comedi_command_test(dio_dev, &cmd);
    if (err != 0) {
        qDebug() << "comedi command failed test.";
        qDebug() << "comedi_command_test result: " <<  err;
        int blah = comedi_get_version_code(dio_dev);
        qDebug() <<
            "COMEDI VER: " <<
            (0x0000ff & (blah >> 16)) <<
            "." << (0x0000ff & (blah >> 8)) <<
            "." << (0x0000ff & blah);

        throw;
    }

    err = comedi_dio_config(timer_dev, 1, 36, COMEDI_OUTPUT);
    if (err != 0) {
        qDebug() << "Failed to set timer to output. Error #: " << err;
        throw;
    }

    err = comedi_command(dio_dev, &cmd);
    if (err < 0) {
        qDebug() << "Failed to start command!";
    }

    abort = false;
    pauseSampling = false;
    _pc = new MDDASPlotConfig();
    _pc->setXMax(8192);
    _pc->setXMin(0);
    _pc->setYMax(8192);
    _pc->setYMin(0);
    _pc->setPMax(256);
    _pc->setPMin(0);

    if (fclose(fp)) {
        qDebug() << "Error closing " << COM_PROC;
        throw;
    }

    qDebug() << "NIDAQ Init complete...";
}

/* close thread */
NIDAQPlugin::~NIDAQPlugin() {
    ni_gpct_stop_pulse_gen(timer_dev, 2);
    /* stop command */
    comedi_cancel(dio_dev, 0);

    comedi_close(dio_dev);
    comedi_close(timer_dev);

    free(daq_dev_file);
    free(timer_dev_file);
}

void NIDAQPlugin::run() {
    int i = 0;
    int j = 0;
    int num_photons = 0;
    int ret = 0;

    fd_set rdset;
    struct timeval timeout;

    timeout.tv_sec = 0;
    timeout.tv_usec = 50000;

    QMutex sleepM;
    QVector<MDDASDataPoint> v;
    sleepM.lock();

    forever {
        mutex.lock();
        if (pauseSampling) {
            qDebug() << "pause";
            if (ni_gpct_stop_pulse_gen(timer_dev, 2) != 0) {
                qDebug() << "failed to pause!";
            }
            condition.wait(&mutex);
            qDebug() << "unpause";
            ni_gpct_start_pulse_gen(timer_dev, 2, STROBE_PERIOD, STROBE_HIGH_T);
        }
        mutex.unlock();

        if (abort) {
            qDebug() << "called abort!" << QThread::currentThread();
            return;
        }

        //qDebug() << "nidaq!";

        FD_ZERO(&rdset);
        FD_SET(comedi_fileno(dio_dev), &rdset);

        ret = select(comedi_fileno(dio_dev) + 1, &rdset, NULL, NULL, &timeout);
        if (ret < 0) {
            qDebug() << "select() error!";
        } else if (ret == 0) {
            /* hit timeout, poll card */
            ret = comedi_poll(dio_dev, 0);
            if (ret < 0) {
                qDebug() << "comedi_poll() error";
            }
        } else if (FD_ISSET(comedi_fileno(dio_dev), &rdset)) {
            /* comedi file descriptor became ready */
            ret = read(comedi_fileno(dio_dev), buf, sizeof(buf));
            if (ret < 0) {
                qDebug() << "read() error!";
            } else if (ret == 0) {
                /* no data */
                //qDebug() << "no data...";
            } else {
                qDebug() << "Got " << ret << " samples";
            }
        }

        condition.wait(&sleepM, 1);

        //qDebug() << "blip" << QThread::currentThread();
        //sleep();
        /* Use a wait condition instead of sleep() so that the thread
           can be awoken. */
        //condition.wait(&sleepM, 100);

    }
}

int NIDAQPlugin::ni_gpct_start_pulse_gen(comedi_t *device,
                                         unsigned subdevice,
                                         unsigned period_ns,
                                         unsigned up_time_ns) {
    int retval;
    lsampl_t counter_mode;
    const unsigned clock_period_ns = 50; /* 20MHz clock */
    unsigned up_ticks, down_ticks;

    retval = comedi_reset(device, subdevice);
    if (retval < 0) return retval;

    retval = comedi_set_gate_source(device,
                                    subdevice,
                                    0,
                                    0,
                                    NI_GPCT_DISABLED_GATE_SELECT | CR_EDGE);
    if (retval < 0) return retval;
    retval = comedi_set_gate_source(device,
                                    subdevice,
                                    0,
                                    1,
                                    NI_GPCT_DISABLED_GATE_SELECT | CR_EDGE);
    if (retval < 0) {
        //fprintf(stderr, "Failed to set second gate source.  This is expected for older boards (e-series, etc.)\n"
        //        "that don't have a second gate.\n");
        qDebug() << "Failed to set second gate source.  This is expected for older boards (e-series, etc.)";
        qDebug() << "that don't have a second gate.";

    }

    counter_mode = NI_GPCT_COUNTING_MODE_NORMAL_BITS;
    /* toggle output on terminal count */
    counter_mode |= NI_GPCT_OUTPUT_TC_TOGGLE_BITS;
    /* load on terminal count */
    counter_mode |= NI_GPCT_LOADING_ON_TC_BIT;
    /* alternate the reload source between the load a and load b registers */
    counter_mode |= NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS;
    /* count down */
    counter_mode |= NI_GPCT_COUNTING_DIRECTION_DOWN_BITS;
    /* initialize load source as load b register */
    counter_mode |= NI_GPCT_LOAD_B_SELECT_BIT;
    /* don't stop on terminal count */
    counter_mode |= NI_GPCT_STOP_ON_GATE_BITS;
    /* don't disarm on terminal count or gate signal */
    counter_mode |= NI_GPCT_NO_HARDWARE_DISARM_BITS;
    retval = comedi_set_counter_mode(device, subdevice, 0, counter_mode);
    if (retval < 0) return retval;

    /* 20MHz clock */
    retval = comedi_set_clock_source(device,
                                     subdevice,
                                     0,
                                     NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS,
                                     clock_period_ns);
    if (retval < 0) return retval;

    up_ticks = (up_time_ns + clock_period_ns / 2) / clock_period_ns;
    down_ticks = (period_ns + clock_period_ns / 2) / clock_period_ns - up_ticks;
    /* set initial counter value by writing to channel 0 */
    retval = comedi_data_write(device, subdevice, 0, 0, 0, down_ticks);
    if (retval < 0) return retval;
    /* set "load a" register to the number of clock ticks the counter
       output should remain low by writing to channel 1. */
    comedi_data_write(device, subdevice, 1, 0, 0, down_ticks);
    if (retval < 0) return retval;
    /* set "load b" register to the number of clock ticks the counter
       output should remain high by writing to channel 2 */
    comedi_data_write(device, subdevice, 2, 0, 0, up_ticks);
    if(retval < 0) return retval;

    retval = comedi_arm(device, subdevice, NI_GPCT_ARM_IMMEDIATE);
    if (retval < 0) return retval;

    return 0;
}

int NIDAQPlugin::ni_gpct_stop_pulse_gen(comedi_t *device, unsigned subdevice) {
    comedi_insn insn;
    lsampl_t data;

    memset(&insn, 0, sizeof(comedi_insn));
    insn.insn = INSN_CONFIG;
    insn.subdev = subdevice;
    insn.chanspec = 0;
    insn.data = &data;
    insn.n = 1;
    data = INSN_CONFIG_DISARM;

    if (comedi_do_insn(device, &insn) >= 0) {
        return 0;
    } else {
        return -1;
    }
}

Q_EXPORT_PLUGIN2(nidaqplugin, NIDAQPlugin);

<|endoftext|>


<commit_before>#include <gst/gst.h>
#include "MediaPipelineImpl.hpp"
#include "MediaObjectImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <gst/gst.h>
#include <UUIDGenerator.hpp>
#include <MediaSet.hpp>

#define GST_CAT_DEFAULT kurento_media_object_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaObjectImpl"

namespace kurento
{

MediaObjectImpl::MediaObjectImpl (const boost::property_tree::ptree &config)
{
  creationTime = time (NULL);
  initialId = createId();
  this->config = config;
  this->sendTagsInEvents = false;
}

MediaObjectImpl::MediaObjectImpl (const boost::property_tree::ptree &config,
                                  std::shared_ptr< MediaObject > parent) : MediaObjectImpl (config)
{
  this->parent = parent;
}

std::shared_ptr<MediaPipeline>
MediaObjectImpl::getMediaPipeline ()
{
  if (parent) {
    return std::dynamic_pointer_cast<MediaObjectImpl> (parent)->getMediaPipeline();
  } else {
    return std::dynamic_pointer_cast<MediaPipeline> (shared_from_this() );
  }
}

std::string
MediaObjectImpl::createId()
{
  std::string uuid = generateUUID();

  if (parent) {
    std::shared_ptr<MediaPipelineImpl> pipeline;

    pipeline = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );
    return pipeline->getId() + "/" +
           uuid;
  } else {
    return uuid;
  }
}

std::string
MediaObjectImpl::getName()
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  if (name.empty () ) {
    name = getId ();
  }

  return name;
}

std::string
MediaObjectImpl::getId()
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  if (id.empty () ) {
    id = this->initialId + "_" + this->getType ();
  }

  return id;
}

void
MediaObjectImpl::setName (const std::string &name)
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  this->name = name;
}

std::vector<std::shared_ptr<MediaObject>> MediaObjectImpl::getChilds ()
{
  std::vector<std::shared_ptr<MediaObject>> childs;

  for (auto it : MediaSet::getMediaSet ()->getChilds (std::dynamic_pointer_cast
       <MediaObjectImpl> (shared_from_this() ) ) ) {
    childs.push_back (it);
  }

  return childs;
}

bool MediaObjectImpl::getSendTagsInEvents ()
{
  return this->sendTagsInEvents;
}

void MediaObjectImpl::setSendTagsInEvents (bool sendTagsInEvents)
{
  this->sendTagsInEvents = sendTagsInEvents;
}

void MediaObjectImpl::addTag (const std::string &key, const std::string &value)
{
  tagsMap [key] = value;
  GST_DEBUG ("Tag added");
}

void MediaObjectImpl::removeTag (const std::string &key)
{
  auto it = tagsMap.find (key);

  if (it != tagsMap.end() ) {
    tagsMap.erase (it);
    GST_DEBUG ("Tag deleted");
    return;
  }

  GST_DEBUG ("Tag not found");
}

std::string MediaObjectImpl::getTag (const std::string &key)
{
  auto it = tagsMap.find (key);

  if (it != tagsMap.end() ) {
    return it->second;
  }

  throw KurentoException (MEDIA_OBJECT_TAG_KEY_NOT_FOUND,
                          "Tag key not found");
}

void MediaObjectImpl::postConstructor()
{
}

std::vector<std::shared_ptr<Tag>> MediaObjectImpl::getTags ()
{
  std::vector<std::shared_ptr<Tag>> ret;

  for (auto it : tagsMap ) {
    std::shared_ptr <Tag> tag (new Tag (it.first, it.second) );
    ret.push_back (tag);
  }

  return ret;
}

int  MediaObjectImpl::getCreationTime ()
{
  return (int) creationTime;
}

MediaObjectImpl::StaticConstructor MediaObjectImpl::staticConstructor;

MediaObjectImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */
<commit_msg>MediaObjectImpl: Fix bug, mediaobjects id didn't containg its parent id<commit_after>#include <gst/gst.h>
#include "MediaPipelineImpl.hpp"
#include "MediaObjectImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <gst/gst.h>
#include <UUIDGenerator.hpp>
#include <MediaSet.hpp>

#define GST_CAT_DEFAULT kurento_media_object_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaObjectImpl"

namespace kurento
{

MediaObjectImpl::MediaObjectImpl (const boost::property_tree::ptree &config) :
  MediaObjectImpl (config, std::shared_ptr<MediaObject> () )
{
}

MediaObjectImpl::MediaObjectImpl (const boost::property_tree::ptree &config,
                                  std::shared_ptr< MediaObject > parent)
{
  this->parent = parent;

  creationTime = time (NULL);
  initialId = createId();
  this->config = config;
  this->sendTagsInEvents = false;
}

std::shared_ptr<MediaPipeline>
MediaObjectImpl::getMediaPipeline ()
{
  if (parent) {
    return std::dynamic_pointer_cast<MediaObjectImpl> (parent)->getMediaPipeline();
  } else {
    return std::dynamic_pointer_cast<MediaPipeline> (shared_from_this() );
  }
}

std::string
MediaObjectImpl::createId()
{
  std::string uuid = generateUUID();

  if (parent) {
    std::shared_ptr<MediaPipelineImpl> pipeline;

    pipeline = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );
    return pipeline->getId() + "/" +
           uuid;
  } else {
    return uuid;
  }
}

std::string
MediaObjectImpl::getName()
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  if (name.empty () ) {
    name = getId ();
  }

  return name;
}

std::string
MediaObjectImpl::getId()
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  if (id.empty () ) {
    id = this->initialId + "_" + this->getType ();
  }

  return id;
}

void
MediaObjectImpl::setName (const std::string &name)
{
  std::unique_lock<std::recursive_mutex> lck (mutex);

  this->name = name;
}

std::vector<std::shared_ptr<MediaObject>> MediaObjectImpl::getChilds ()
{
  std::vector<std::shared_ptr<MediaObject>> childs;

  for (auto it : MediaSet::getMediaSet ()->getChilds (std::dynamic_pointer_cast
       <MediaObjectImpl> (shared_from_this() ) ) ) {
    childs.push_back (it);
  }

  return childs;
}

bool MediaObjectImpl::getSendTagsInEvents ()
{
  return this->sendTagsInEvents;
}

void MediaObjectImpl::setSendTagsInEvents (bool sendTagsInEvents)
{
  this->sendTagsInEvents = sendTagsInEvents;
}

void MediaObjectImpl::addTag (const std::string &key, const std::string &value)
{
  tagsMap [key] = value;
  GST_DEBUG ("Tag added");
}

void MediaObjectImpl::removeTag (const std::string &key)
{
  auto it = tagsMap.find (key);

  if (it != tagsMap.end() ) {
    tagsMap.erase (it);
    GST_DEBUG ("Tag deleted");
    return;
  }

  GST_DEBUG ("Tag not found");
}

std::string MediaObjectImpl::getTag (const std::string &key)
{
  auto it = tagsMap.find (key);

  if (it != tagsMap.end() ) {
    return it->second;
  }

  throw KurentoException (MEDIA_OBJECT_TAG_KEY_NOT_FOUND,
                          "Tag key not found");
}

void MediaObjectImpl::postConstructor()
{
}

std::vector<std::shared_ptr<Tag>> MediaObjectImpl::getTags ()
{
  std::vector<std::shared_ptr<Tag>> ret;

  for (auto it : tagsMap ) {
    std::shared_ptr <Tag> tag (new Tag (it.first, it.second) );
    ret.push_back (tag);
  }

  return ret;
}

int  MediaObjectImpl::getCreationTime ()
{
  return (int) creationTime;
}

MediaObjectImpl::StaticConstructor MediaObjectImpl::staticConstructor;

MediaObjectImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */
<|endoftext|>


<commit_before><commit_msg>iahndl: do lazy replacement<commit_after><|endoftext|>


<commit_before>#include <config.h>
#ifdef SYSTEM_UNIX
#include <sys/prctl.h>
#include <sys/wait.h>
#endif

#include <boost/lexical_cast.hpp>

#include "typename.h"
#include "Logger.h"
#include "demangle.h"
#include "exceptions.h"

logger::LogChannel tracelog("tracelog", "[trace] ");

stack_trace_::stack_trace_() {

#ifdef SYSTEM_UNIX
	std::string programName = get_program_name();
	std::string pid         = get_pid();

	_stack_trace.push_back(std::string("\t[trace] back trace for ") + programName + " (" + pid + "):");

	// create a pipe to read gdb's output
	int pipefds[2];
	int res = pipe(pipefds);
	if (res < 0)
		return;

	// create a pipe to be used as a barrier
	int barrierfds[2];
	res = pipe(barrierfds);
	if (res < 0)
		return;

	// fork
	int childPid = fork();

	// child:
	if (!childPid) {

		LOG_ALL(tracelog) << "[child] waiting for parent process to allow attaching" << std::endl;

		// close writing end of barrier pipe
		close(barrierfds[1]);

		// wait until parent closes barrier pipe
		char buf[1];
		while (read(barrierfds[0], buf, sizeof(buf)) > 0)
			LOG_ALL(tracelog) << "[child] " << buf[0] << std::endl;

		LOG_ALL(tracelog) << "[child] parent process closed barrier pipe, preparing gdb invocation" << std::endl;

		// close barrier pipe
		close(barrierfds[0]);

		// close reading end of output pipe
		close(pipefds[0]);

		// redirect stdout and stderr to output pipe
		dup2(pipefds[1], 1);
		dup2(pipefds[1], 2);

		// close writing end of pipe (_we_ don't need it any longer)
		close(pipefds[1]);

		// start gdb
		execlp("gdb", "gdb", "--batch", "-n", "-ex", "bt full", programName.c_str(), pid.c_str(), NULL);

	// parent:
	} else {

		LOG_ALL(tracelog) << "[parent] allowing child to attach" << std::endl;

		// allow our child process to attach
		prctl(PR_SET_PTRACER, childPid, 0, 0, 0);

		LOG_ALL(tracelog) << "[parent] closing barrier pipe" << std::endl;

		// close barrier pipe to let child proceed
		close(barrierfds[0]);
		close(barrierfds[1]);

		LOG_ALL(tracelog) << "[parent] barrier pipe closed" << std::endl;

		// close the write end of pipe
		close(pipefds[1]);

		// capture child's output
		std::string output;

		// read the whole output of gdb
		char   buf[1];
		size_t n;
		while ((n = read(pipefds[0], buf, sizeof(buf))))
			output += std::string(buf, n);

		LOG_ALL(tracelog) << "[parent] end of pipe; I read: " << std::endl << output << std::endl;

		// split it at newline characters
		std::stringstream oss(output);
		std::string       line;

		// ignore every line until '#0 ...'
		while (std::getline(oss, line) && (line.size() < 2 || (line[0] != '#' && line[1] != '0')));

		// copy remaining lines to stack trace
		do {

			if (line.size() > 0 && line[0] != '\n')
				_stack_trace.push_back(std::string("\t[trace] ") + line);

		} while (std::getline(oss, line));

		// wait for the child to finish
		waitpid(childPid, NULL, 0);
	}

#endif // SYSTEM_UNIX

	return;
}

const std::vector<std::string>&
stack_trace_::get_stack_trace() const {

	return _stack_trace;
}

const std::string&
stack_trace_::get_program_name() {

	if (_program_name == "")
		initialise_program_name();

	return _program_name;
}

std::string
stack_trace_::get_pid() {

#ifdef SYSTEM_UNIX
	return boost::lexical_cast<std::string>(getpid());
#else
	return "unknown";
#endif
}

void
stack_trace_::initialise_program_name() {

#ifdef SYSTEM_UNIX
	char link[1024];
	char name[1024];

	snprintf(link, sizeof link, "/proc/%d/exe", getpid());

	int size = readlink(link, name, sizeof link);
	if (size == -1) {

		_program_name = "[program name not found]";
		return;
	}

	for (int i = 0; i < size; i++)
		_program_name += name[i];
#endif
}

void handleException(const boost::exception& e, std::ostream& out) {

	out << std::endl;
	out << "caught exception" << std::endl << std::endl;

	if (boost::get_error_info<stack_trace>(e)) {

		out << "###############" << std::endl;
		out << "# STACK TRACE #" << std::endl;
		out << "###############" << std::endl;
		out << std::endl << std::endl;
		out << *boost::get_error_info<stack_trace>(e);
		out << std::endl << std::endl;
	}

	out << "#####################" << std::endl;
	out << "# EXCEPTION SUMMARY #" << std::endl;
	out << "#####################" << std::endl;
	out << std::endl << std::endl;

	out << "exception type:" << std::endl << std::endl << "\t" << typeName(e) << std::endl << std::endl;

	if (boost::get_error_info<boost::throw_function>(e)) {

		out << "throw location:" << std::endl << std::endl;
		out << "\t" << *boost::get_error_info<boost::throw_function>(e) << std::endl;

		if (boost::get_error_info<boost::throw_file>(e)) {

			out << "\tin " << *boost::get_error_info<boost::throw_file>(e);
			if (boost::get_error_info<boost::throw_line>(e))
				out << "(" << *boost::get_error_info<boost::throw_line>(e) << ")";
		}

		out << std::endl;
	}

	if (boost::get_error_info<error_message>(e)) {

		out << std::endl << "error message:" << std::endl << std::endl;;
		out << "\t" << *boost::get_error_info<error_message>(e);
		out << std::endl << std::endl;
	}
}

std::ostream& operator<<(std::ostream& out, const stack_trace_& trace) {

	for (unsigned int i = 0; i < trace.get_stack_trace().size(); i++)
		out << trace.get_stack_trace()[i] << std::endl;

	return out;
}
<commit_msg>Compile fix for MAC<commit_after>#include <config.h>
#if defined(SYSTEM_UNIX) && !defined(SYSTEM_MAC)
#include <sys/prctl.h>
#include <sys/wait.h>
#endif

#include <boost/lexical_cast.hpp>

#include "typename.h"
#include "Logger.h"
#include "demangle.h"
#include "exceptions.h"

logger::LogChannel tracelog("tracelog", "[trace] ");

stack_trace_::stack_trace_() {

#if defined(SYSTEM_UNIX) && !defined(SYSTEM_MAC)
	std::string programName = get_program_name();
	std::string pid         = get_pid();

	_stack_trace.push_back(std::string("\t[trace] back trace for ") + programName + " (" + pid + "):");

	// create a pipe to read gdb's output
	int pipefds[2];
	int res = pipe(pipefds);
	if (res < 0)
		return;

	// create a pipe to be used as a barrier
	int barrierfds[2];
	res = pipe(barrierfds);
	if (res < 0)
		return;

	// fork
	int childPid = fork();

	// child:
	if (!childPid) {

		LOG_ALL(tracelog) << "[child] waiting for parent process to allow attaching" << std::endl;

		// close writing end of barrier pipe
		close(barrierfds[1]);

		// wait until parent closes barrier pipe
		char buf[1];
		while (read(barrierfds[0], buf, sizeof(buf)) > 0)
			LOG_ALL(tracelog) << "[child] " << buf[0] << std::endl;

		LOG_ALL(tracelog) << "[child] parent process closed barrier pipe, preparing gdb invocation" << std::endl;

		// close barrier pipe
		close(barrierfds[0]);

		// close reading end of output pipe
		close(pipefds[0]);

		// redirect stdout and stderr to output pipe
		dup2(pipefds[1], 1);
		dup2(pipefds[1], 2);

		// close writing end of pipe (_we_ don't need it any longer)
		close(pipefds[1]);

		// start gdb
		execlp("gdb", "gdb", "--batch", "-n", "-ex", "bt full", programName.c_str(), pid.c_str(), NULL);

	// parent:
	} else {

		LOG_ALL(tracelog) << "[parent] allowing child to attach" << std::endl;

		// allow our child process to attach
		prctl(PR_SET_PTRACER, childPid, 0, 0, 0);

		LOG_ALL(tracelog) << "[parent] closing barrier pipe" << std::endl;

		// close barrier pipe to let child proceed
		close(barrierfds[0]);
		close(barrierfds[1]);

		LOG_ALL(tracelog) << "[parent] barrier pipe closed" << std::endl;

		// close the write end of pipe
		close(pipefds[1]);

		// capture child's output
		std::string output;

		// read the whole output of gdb
		char   buf[1];
		size_t n;
		while ((n = read(pipefds[0], buf, sizeof(buf))))
			output += std::string(buf, n);

		LOG_ALL(tracelog) << "[parent] end of pipe; I read: " << std::endl << output << std::endl;

		// split it at newline characters
		std::stringstream oss(output);
		std::string       line;

		// ignore every line until '#0 ...'
		while (std::getline(oss, line) && (line.size() < 2 || (line[0] != '#' && line[1] != '0')));

		// copy remaining lines to stack trace
		do {

			if (line.size() > 0 && line[0] != '\n')
				_stack_trace.push_back(std::string("\t[trace] ") + line);

		} while (std::getline(oss, line));

		// wait for the child to finish
		waitpid(childPid, NULL, 0);
	}

#endif // SYSTEM_UNIX && !SYSTEM_MAC

	return;
}

const std::vector<std::string>&
stack_trace_::get_stack_trace() const {

	return _stack_trace;
}

const std::string&
stack_trace_::get_program_name() {

	if (_program_name == "")
		initialise_program_name();

	return _program_name;
}

std::string
stack_trace_::get_pid() {

#if defined(SYSTEM_UNIX) && !defined(SYSTEM_MAC)
	return boost::lexical_cast<std::string>(getpid());
#else
	return "unknown";
#endif
}

void
stack_trace_::initialise_program_name() {

#if defined(SYSTEM_UNIX) && !defined(SYSTEM_MAC)
	char link[1024];
	char name[1024];

	snprintf(link, sizeof link, "/proc/%d/exe", getpid());

	int size = readlink(link, name, sizeof link);
	if (size == -1) {

		_program_name = "[program name not found]";
		return;
	}

	for (int i = 0; i < size; i++)
		_program_name += name[i];
#endif
}

void handleException(const boost::exception& e, std::ostream& out) {

	out << std::endl;
	out << "caught exception" << std::endl << std::endl;

	if (boost::get_error_info<stack_trace>(e)) {

		out << "###############" << std::endl;
		out << "# STACK TRACE #" << std::endl;
		out << "###############" << std::endl;
		out << std::endl << std::endl;
		out << *boost::get_error_info<stack_trace>(e);
		out << std::endl << std::endl;
	}

	out << "#####################" << std::endl;
	out << "# EXCEPTION SUMMARY #" << std::endl;
	out << "#####################" << std::endl;
	out << std::endl << std::endl;

	out << "exception type:" << std::endl << std::endl << "\t" << typeName(e) << std::endl << std::endl;

	if (boost::get_error_info<boost::throw_function>(e)) {

		out << "throw location:" << std::endl << std::endl;
		out << "\t" << *boost::get_error_info<boost::throw_function>(e) << std::endl;

		if (boost::get_error_info<boost::throw_file>(e)) {

			out << "\tin " << *boost::get_error_info<boost::throw_file>(e);
			if (boost::get_error_info<boost::throw_line>(e))
				out << "(" << *boost::get_error_info<boost::throw_line>(e) << ")";
		}

		out << std::endl;
	}

	if (boost::get_error_info<error_message>(e)) {

		out << std::endl << "error message:" << std::endl << std::endl;;
		out << "\t" << *boost::get_error_info<error_message>(e);
		out << std::endl << std::endl;
	}
}

std::ostream& operator<<(std::ostream& out, const stack_trace_& trace) {

	for (unsigned int i = 0; i < trace.get_stack_trace().size(); i++)
		out << trace.get_stack_trace()[i] << std::endl;

	return out;
}
<|endoftext|>


<commit_before>//DEFINITION OF A FEW CONSTANTS

AliPWG4HighPtQAMC* AddTaskPWG4HighPtQAMC()
{
  // Creates HighPtQAMC analysis task and adds it to the analysis manager.

  // A. Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskPWG4HighPtQMC", "No analysis manager to connect to.");
    return NULL;
  }

  // B. Check the analysis type using the event handlers connected to the analysis
  //    manager. The availability of MC handler can also be checked here.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddPWG4TaskHighPtQAMC", "This task requires an input event handler");
    return NULL;
  }
  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  const char *analysisType = "ESD";//"TPC"

  // C. Create the task, add it to manager.
  //===========================================================================

  //CREATE THE  CUTS -----------------------------------------------
  //Use AliESDtrackCuts
  AliESDtrackCuts *trackCuts = new AliESDtrackCuts("AliESDtrackCuts","Standard Cuts");
  //Standard Cuts
  trackCuts=trackCuts->GetStandardITSTPCTrackCuts2009(kTRUE);//Primary Track Selection
  trackCuts->SetEtaRange(-0.9,0.9);
  trackCuts->SetPtRange(0.15, 1e10);
  trackCuts->SetRequireITSRefit(kFALSE);

  AliESDtrackCuts *trackCutsITS = new AliESDtrackCuts("AliESDtrackCuts","Standard Cuts with ITSrefit");
  //Standard Cuts
  trackCuts=trackCuts->GetStandardITSTPCTrackCuts2009(kTRUE);//Primary Track Selection
  trackCuts->SetEtaRange(-0.9,0.9);
  trackCuts->SetPtRange(0.15, 1e10);
  trackCuts->SetRequireITSRefit(kTRUE);

  //Create the task
  AliPWG4HighPtQAMC *taskPWG4QAMC = new AliPWG4HighPtQAMC("AliPWG4HighPtQAMC");
  taskPWG4QAMC->SetCuts(trackCuts);
  taskPWG4QAMC->SetCutsITS(trackCutsITS);

  // E. Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================

  //------ input data ------
  //  AliAnalysisDataContainer *cinput0  = mgr->GetCommonInputContainer();
  printf("Create output containers \n");
  TString outputfile = AliAnalysisManager::GetCommonFileName();
  outputfile += ":PWG4_HighPtQAMC";
  //char *outputfile = "outputAliPWG4HighPtQAMCTestTrain.root";
  AliAnalysisDataContainer *cout_hist0 = mgr->CreateContainer("qa_histsMC", TList::Class(), AliAnalysisManager::kOutputContainer,outputfile);
  AliAnalysisDataContainer *cout_hist2 = mgr->CreateContainer("qa_histsMCITS", TList::Class(), AliAnalysisManager::kOutputContainer,outputfile);

  mgr->AddTask(taskPWG4QAMC);
  mgr->ConnectInput(taskPWG4QAMC,0,mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskPWG4QAMC,0,cout_hist0);
  mgr->ConnectOutput(taskPWG4QAMC,1,cout_hist2);

  // Return task pointer at the end
  return taskPWG4QAMC;
}
<commit_msg>bug fix in definition of track cuts (Marta)<commit_after>//DEFINITION OF A FEW CONSTANTS

AliPWG4HighPtQAMC* AddTaskPWG4HighPtQAMC()
{
  // Creates HighPtQAMC analysis task and adds it to the analysis manager.

  // A. Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskPWG4HighPtQMC", "No analysis manager to connect to.");
    return NULL;
  }

  // B. Check the analysis type using the event handlers connected to the analysis
  //    manager. The availability of MC handler can also be checked here.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddPWG4TaskHighPtQAMC", "This task requires an input event handler");
    return NULL;
  }
  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  const char *analysisType = "ESD";//"TPC"

  // C. Create the task, add it to manager.
  //===========================================================================

  //CREATE THE  CUTS -----------------------------------------------
  //Use AliESDtrackCuts
  AliESDtrackCuts *trackCuts = new AliESDtrackCuts("AliESDtrackCuts","Standard Cuts");
  //Standard Cuts
  trackCuts=trackCuts->GetStandardITSTPCTrackCuts2009(kTRUE);//Primary Track Selection
  trackCuts->SetEtaRange(-0.9,0.9);
  trackCuts->SetPtRange(0.15, 1e10);
  trackCuts->SetRequireITSRefit(kFALSE);

  AliESDtrackCuts *trackCutsITS = new AliESDtrackCuts("AliESDtrackCuts","Standard Cuts with ITSrefit");
  //Standard Cuts
  trackCutsITS=trackCuts->GetStandardITSTPCTrackCuts2009(kTRUE);//Primary Track Selection
  trackCutsITS->SetEtaRange(-0.9,0.9);
  trackCutsITS->SetPtRange(0.15, 1e10);
  trackCutsITS->SetRequireITSRefit(kTRUE);

  //Create the task
  AliPWG4HighPtQAMC *taskPWG4QAMC = new AliPWG4HighPtQAMC("AliPWG4HighPtQAMC");
  taskPWG4QAMC->SetCuts(trackCuts);
  taskPWG4QAMC->SetCutsITS(trackCutsITS);

  // E. Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================

  //------ input data ------
  //  AliAnalysisDataContainer *cinput0  = mgr->GetCommonInputContainer();
  printf("Create output containers \n");
  TString outputfile = AliAnalysisManager::GetCommonFileName();
  outputfile += ":PWG4_HighPtQAMC";
  //char *outputfile = "outputAliPWG4HighPtQAMCTestTrain.root";
  AliAnalysisDataContainer *cout_hist0 = mgr->CreateContainer("qa_histsMC", TList::Class(), AliAnalysisManager::kOutputContainer,outputfile);
  AliAnalysisDataContainer *cout_hist2 = mgr->CreateContainer("qa_histsMCITS", TList::Class(), AliAnalysisManager::kOutputContainer,outputfile);

  mgr->AddTask(taskPWG4QAMC);
  mgr->ConnectInput(taskPWG4QAMC,0,mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskPWG4QAMC,0,cout_hist0);
  mgr->ConnectOutput(taskPWG4QAMC,1,cout_hist2);

  // Return task pointer at the end
  return taskPWG4QAMC;
}
<|endoftext|>