<commit_before>/*
 * extract.cpp
 *	Modified by: Rohit Gupta CDAC, Mumbai, India
 *	on July 15, 2012 to implement parallel processing
 *      Modified by: Nadi Tomeh - LIMSI/CNRS
 *      Machine Translation Marathon 2010, Dublin
 */

#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <cstring>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <limits>

#include "SentenceAlignment.h"
#include "tables-core.h"
#include "InputFileStream.h"
#include "OutputFileStream.h"
#include "PhraseExtractionOptions.h"

using namespace std;
using namespace MosesTraining;

namespace MosesTraining
{

// HPhraseVertex represents a point in the alignment matrix
typedef pair <int, int> HPhraseVertex;

// Phrase represents a bi-phrase; each bi-phrase is defined by two points in the alignment matrix:
// bottom-left and top-right
typedef pair<HPhraseVertex, HPhraseVertex> HPhrase;

// HPhraseVector is a vector of HPhrases
typedef vector < HPhrase > HPhraseVector;

// SentenceVertices represents, from all extracted phrases, all vertices that have the same positioning
// The key of the map is the English index and the value is a set of the source ones
typedef map <int, set<int> > HSentenceVertices;

REO_POS getOrientWordModel(SentenceAlignment &, REO_MODEL_TYPE, bool, bool,
                           int, int, int, int, int, int, int,
                           bool (*)(int, int), bool (*)(int, int));
REO_POS getOrientPhraseModel(SentenceAlignment &, REO_MODEL_TYPE, bool, bool,
                             int, int, int, int, int, int, int,
                             bool (*)(int, int), bool (*)(int, int),
                             const HSentenceVertices &, const HSentenceVertices &);
REO_POS getOrientHierModel(SentenceAlignment &, REO_MODEL_TYPE, bool, bool,
                           int, int, int, int, int, int, int,
                           bool (*)(int, int), bool (*)(int, int),
                           const HSentenceVertices &, const HSentenceVertices &,
                           const HSentenceVertices &, const HSentenceVertices &,
                           REO_POS);

void insertVertex(HSentenceVertices &, int, int);
void insertPhraseVertices(HSentenceVertices &, HSentenceVertices &, HSentenceVertices &, HSentenceVertices &,
                          int, int, int, int);
string getOrientString(REO_POS, REO_MODEL_TYPE);

bool ge(int, int);
bool le(int, int);
bool lt(int, int);

bool isAligned (SentenceAlignment &, int, int);

int sentenceOffset = 0;

std::vector<std::string> Tokenize(const std::string& str,
                                  const std::string& delimiters = " \t");

bool flexScoreFlag = false;

}

namespace MosesTraining
{

class ExtractTask
{
public:
  ExtractTask(size_t id, SentenceAlignment &sentence,PhraseExtractionOptions &initoptions, Moses::OutputFileStream &extractFileOrientation)
    :m_sentence(sentence),
    m_options(initoptions),
    m_extractFileOrientation(extractFileOrientation)
	{}
  void Run();
private:
  void extract(SentenceAlignment &);
  void addPhrase(SentenceAlignment &, int, int, int, int, string &);
  void writePhrasesToFile();

  SentenceAlignment &m_sentence;
  const PhraseExtractionOptions &m_options;
  Moses::OutputFileStream &m_extractFileOrientation;
};
}

int main(int argc, char* argv[])
{
  cerr	<< "PhraseExtract v1.4, written by Philipp Koehn\n"
        << "phrase extraction from an aligned parallel corpus\n";

  if (argc < 6) {
    cerr << "syntax: extract en de align extract max-length [orientation [ --model [wbe|phrase|hier]-[msd|mslr|mono] ] ";
    cerr<<"| --OnlyOutputSpanInfo | --NoTTable | --GZOutput | --IncludeSentenceId | --SentenceOffset n | --InstanceWeights filename ]\n";
    exit(1);
  }

  Moses::OutputFileStream extractFileOrientation;
  const char* const &fileNameE = argv[1];
  const char* const &fileNameF = argv[2];
  const char* const &fileNameA = argv[3];
  const string fileNameExtract = string(argv[4]);
  PhraseExtractionOptions options(atoi(argv[5]));

  for(int i=6; i<argc; i++) {
    if (strcmp(argv[i],"--OnlyOutputSpanInfo") == 0) {
      options.initOnlyOutputSpanInfo(true);
    } else if (strcmp(argv[i],"orientation") == 0 || strcmp(argv[i],"--Orientation") == 0) {
      options.initOrientationFlag(true);
    } else if (strcmp(argv[i],"--FlexibilityScore") == 0) {
      options.initFlexScoreFlag(true);
    } else if (strcmp(argv[i],"--NoTTable") == 0) {
      options.initTranslationFlag(false);
    } else if (strcmp(argv[i], "--IncludeSentenceId") == 0) {
      options.initIncludeSentenceIdFlag(true);
    } else if (strcmp(argv[i], "--SentenceOffset") == 0) {
      if (i+1 >= argc || argv[i+1][0] < '0' || argv[i+1][0] > '9') {
        cerr << "extract: syntax error, used switch --SentenceOffset without a number" << endl;
        exit(1);
      }
      sentenceOffset = atoi(argv[++i]);
    } else if (strcmp(argv[i], "--GZOutput") == 0) {
      options.initGzOutput(true);
    } else if (strcmp(argv[i], "--InstanceWeights") == 0) {
      if (i+1 >= argc) {
        cerr << "extract: syntax error, used switch --InstanceWeights without file name" << endl;
        exit(1);
      }
      options.initInstanceWeightsFile(argv[++i]);
    } else if (strcmp(argv[i], "--Debug") == 0) {
    	options.debug = true;
    } else if (strcmp(argv[i], "--MinPhraseLength") == 0) {
    	options.minPhraseLength = atoi(argv[++i]);
    } else if (strcmp(argv[i], "--Separator") == 0) {
    	options.separator = argv[++i];
    } else if(strcmp(argv[i],"--model") == 0) {
      if (i+1 >= argc) {
        cerr << "extract: syntax error, no model's information provided to the option --model " << endl;
        exit(1);
      }
      char*  modelParams = argv[++i];
      char*  modelName = strtok(modelParams, "-");
      char*  modelType = strtok(NULL, "-");

      // REO_MODEL_TYPE intModelType;

      if(strcmp(modelName, "wbe") == 0) {
        options.initWordModel(true);
        if(strcmp(modelType, "msd") == 0)
          options.initWordType(REO_MSD);
        else if(strcmp(modelType, "mslr") == 0)
          options.initWordType(REO_MSLR);
        else if(strcmp(modelType, "mono") == 0 || strcmp(modelType, "monotonicity") == 0)
          options.initWordType(REO_MONO);
        else {
          cerr << "extract: syntax error, unknown reordering model type: " << modelType << endl;
          exit(1);
        }
      } else if(strcmp(modelName, "phrase") == 0) {
        options.initPhraseModel(true);
        if(strcmp(modelType, "msd") == 0)
          options.initPhraseType(REO_MSD);
        else if(strcmp(modelType, "mslr") == 0)
          options.initPhraseType(REO_MSLR);
        else if(strcmp(modelType, "mono") == 0 || strcmp(modelType, "monotonicity") == 0)
          options.initPhraseType(REO_MONO);
        else {
          cerr << "extract: syntax error, unknown reordering model type: " << modelType << endl;
          exit(1);
        }
      } else if(strcmp(modelName, "hier") == 0) {
        options.initHierModel(true);
        if(strcmp(modelType, "msd") == 0)
          options.initHierType(REO_MSD);
        else if(strcmp(modelType, "mslr") == 0)
          options.initHierType(REO_MSLR);
        else if(strcmp(modelType, "mono") == 0 || strcmp(modelType, "monotonicity") == 0)
          options.initHierType(REO_MONO);
        else {
          cerr << "extract: syntax error, unknown reordering model type: " << modelType << endl;
          exit(1);
        }
      } else {
        cerr << "extract: syntax error, unknown reordering model: " << modelName << endl;
        exit(1);
      }

      options.initAllModelsOutputFlag(true);
    } else {
      cerr << "extract: syntax error, unknown option '" << string(argv[i]) << "'\n";
      exit(1);
    }
  }

  // default reordering model if no model selected
  // allows for the old syntax to be used
  if(options.isOrientationFlag() && !options.isAllModelsOutputFlag()) {
    options.initWordModel(true);
    options.initWordType(REO_MSD);
  }

  // open input files
  Moses::InputFileStream eFile(fileNameE);
  Moses::InputFileStream fFile(fileNameF);
  Moses::InputFileStream aFile(fileNameA);

  istream *eFileP = &eFile;
  istream *fFileP = &fFile;
  istream *aFileP = &aFile;

  istream *iwFileP = NULL;
  auto_ptr<Moses::InputFileStream> instanceWeightsFile;
  if (options.getInstanceWeightsFile().length()) {
    instanceWeightsFile.reset(new Moses::InputFileStream(options.getInstanceWeightsFile()));
    iwFileP = instanceWeightsFile.get();
  }

  // open output files
  if (options.isOrientationFlag()) {
    string fileNameExtractOrientation = fileNameExtract + ".o" + (options.isGzOutput()?".gz":"");
    extractFileOrientation.Open(fileNameExtractOrientation.c_str());
  }

  int i = sentenceOffset;

  string englishString, foreignString, alignmentString, weightString;

  while(getline(*eFileP, englishString)) {
    i++;

    getline(*eFileP, englishString);
    getline(*fFileP, foreignString);
    getline(*aFileP, alignmentString);
    if (iwFileP) {
      getline(*iwFileP, weightString);
    }

    if (i%10000 == 0) cerr << "." << flush;

    SentenceAlignment sentence;
    // cout << "read in: " << englishString << " & " << foreignString << " & " << alignmentString << endl;
    //az: output src, tgt, and alingment line
    if (options.isOnlyOutputSpanInfo()) {
      cout << "LOG: SRC: " << foreignString << endl;
      cout << "LOG: TGT: " << englishString << endl;
      cout << "LOG: ALT: " << alignmentString << endl;
      cout << "LOG: PHRASES_BEGIN:" << endl;
    }
    if (sentence.create( englishString.c_str(), foreignString.c_str(), alignmentString.c_str(), weightString.c_str(), i, false)) {
      ExtractTask *task = new ExtractTask(i-1, sentence, options, extractFileOrientation);
      task->Run();
      delete task;

    }
    if (options.isOnlyOutputSpanInfo()) cout << "LOG: PHRASES_END:" << endl; //az: mark end of phrases
  }

  eFile.Close();
  fFile.Close();
  aFile.Close();

  //az: only close if we actually opened it
  if (!options.isOnlyOutputSpanInfo()) {
    if (options.isOrientationFlag()) {
      extractFileOrientation.Close();
    }
  }
}

namespace MosesTraining
{
void ExtractTask::Run()
{
  extract(m_sentence);
}

void ExtractTask::extract(SentenceAlignment &sentence)
{
  int countE = sentence.target.size();
  int countF = sentence.source.size();

  HPhraseVector inboundPhrases;

  HSentenceVertices inTopLeft;
  HSentenceVertices inTopRight;
  HSentenceVertices inBottomLeft;
  HSentenceVertices inBottomRight;

  HSentenceVertices outTopLeft;
  HSentenceVertices outTopRight;
  HSentenceVertices outBottomLeft;
  HSentenceVertices outBottomRight;

  HSentenceVertices::const_iterator it;

  bool relaxLimit = m_options.isHierModel();
  bool buildExtraStructure = m_options.isPhraseModel() || m_options.isHierModel();

  // check alignments for target phrase startE...endE
  // loop over extracted phrases which are compatible with the word-alignments
  for(int startE=0; startE<countE; startE++) {
    for(int endE=startE;
        (endE<countE && (relaxLimit || endE<startE+m_options.maxPhraseLength));
        endE++) {

      int minF = std::numeric_limits<int>::max();
      int maxF = -1;
      vector< int > usedF = sentence.alignedCountS;
      for(int ei=startE; ei<=endE; ei++) {
        for(size_t i=0; i<sentence.alignedToT[ei].size(); i++) {
          int fi = sentence.alignedToT[ei][i];
          if (fi<minF) {
            minF = fi;
          }
          if (fi>maxF) {
            maxF = fi;
          }
          usedF[ fi ]--;
        }
      }

      if (maxF >= 0 && // aligned to any source words at all
          (relaxLimit || maxF-minF < m_options.maxPhraseLength)) { // source phrase within limits

        // check if source words are aligned to out of bound target words
        bool out_of_bounds = false;
        for(int fi=minF; fi<=maxF && !out_of_bounds; fi++)
          if (usedF[fi]>0) {
            // cout << "ouf of bounds: " << fi << "\n";
            out_of_bounds = true;
          }

        // cout << "doing if for ( " << minF << "-" << maxF << ", " << startE << "," << endE << ")\n";
        if (!out_of_bounds) {
          // start point of source phrase may retreat over unaligned
          for(int startF=minF;
              (startF>=0 &&
               (relaxLimit || startF>maxF-m_options.maxPhraseLength) && // within length limit
               (startF==minF || sentence.alignedCountS[startF]==0)); // unaligned
              startF--)
            // end point of source phrase may advance over unaligned
            for(int endF=maxF;
                (endF<countF &&
                 (relaxLimit || endF<startF+m_options.maxPhraseLength) && // within length limit
                 (endF - startF + 1 > m_options.minPhraseLength) && // within length limit
                 (endF==maxF || sentence.alignedCountS[endF]==0)); // unaligned
                endF++) { // at this point we have extracted a phrase
              if(buildExtraStructure) { // phrase || hier
                if(endE-startE < m_options.maxPhraseLength && endF-startF < m_options.maxPhraseLength) { // within limit
                  inboundPhrases.push_back(HPhrase(HPhraseVertex(startF,startE),
                                                   HPhraseVertex(endF,endE)));
                  insertPhraseVertices(inTopLeft, inTopRight, inBottomLeft, inBottomRight,
                                       startF, startE, endF, endE);
                } else
                  insertPhraseVertices(outTopLeft, outTopRight, outBottomLeft, outBottomRight,
                                       startF, startE, endF, endE);
              } else {
                string orientationInfo = "";
                if(m_options.isWordModel()) {
                  REO_POS wordPrevOrient, wordNextOrient;
                  bool connectedLeftTopP  = isAligned( sentence, startF-1, startE-1 );
                  bool connectedRightTopP = isAligned( sentence, endF+1,   startE-1 );
                  bool connectedLeftTopN  = isAligned( sentence, endF+1, endE+1 );
                  bool connectedRightTopN = isAligned( sentence, startF-1,   endE+1 );
                  wordPrevOrient = getOrientWordModel(sentence, m_options.isWordType(), connectedLeftTopP, connectedRightTopP, startF, endF, startE, endE, countF, 0, 1, &ge, &lt);
                  wordNextOrient = getOrientWordModel(sentence, m_options.isWordType(), connectedLeftTopN, connectedRightTopN, endF, startF, endE, startE, 0, countF, -1, &lt, &ge);
                  orientationInfo += getOrientString(wordPrevOrient, m_options.isWordType()) + " " + getOrientString(wordNextOrient, m_options.isWordType());
                  if(m_options.isAllModelsOutputFlag())
                    " | | ";
                }
                addPhrase(sentence, startE, endE, startF, endF, orientationInfo);
              }
            }
        }
      }
    }
  }

}

REO_POS getOrientWordModel(SentenceAlignment & sentence, REO_MODEL_TYPE modelType,
                           bool connectedLeftTop, bool connectedRightTop,
                           int startF, int endF, int startE, int endE, int countF, int zero, int unit,
                           bool (*ge)(int, int), bool (*lt)(int, int) )
{

  if( connectedLeftTop && !connectedRightTop)
    return LEFT;
  if(modelType == REO_MONO)
    return UNKNOWN;
  if (!connectedLeftTop &&  connectedRightTop)
    return RIGHT;
  if(modelType == REO_MSD)
    return UNKNOWN;
  for(int indexF=startF-2*unit; (*ge)(indexF, zero) && !connectedLeftTop; indexF=indexF-unit)
    connectedLeftTop = isAligned(sentence, indexF, startE-unit);
  for(int indexF=endF+2*unit; (*lt)(indexF,countF) && !connectedRightTop; indexF=indexF+unit)
    connectedRightTop = isAligned(sentence, indexF, startE-unit);
  if(connectedLeftTop && !connectedRightTop)
    return DRIGHT;
  else if(!connectedLeftTop && connectedRightTop)
    return DLEFT;
  return UNKNOWN;
}

// to be called with countF-1 instead of countF
REO_POS getOrientPhraseModel (SentenceAlignment & sentence, REO_MODEL_TYPE modelType,
                              bool connectedLeftTop, bool connectedRightTop,
                              int startF, int endF, int startE, int endE, int countF, int zero, int unit,
                              bool (*ge)(int, int), bool (*lt)(int, int),
                              const HSentenceVertices & inBottomRight, const HSentenceVertices & inBottomLeft)
{

  HSentenceVertices::const_iterator it;

  if((connectedLeftTop && !connectedRightTop) ||
      //(startE == 0 && startF == 0) ||
      //(startE == sentence.target.size()-1 && startF == sentence.source.size()-1) ||
      ((it = inBottomRight.find(startE - unit)) != inBottomRight.end() &&
       it->second.find(startF-unit) != it->second.end()))
    return LEFT;
  if(modelType == REO_MONO)
    return UNKNOWN;
  if((!connectedLeftTop &&  connectedRightTop) ||
      ((it = inBottomLeft.find(startE - unit)) != inBottomLeft.end() && it->second.find(endF + unit) != it->second.end()))
    return RIGHT;
  if(modelType == REO_MSD)
    return UNKNOWN;
  connectedLeftTop = false;
  for(int indexF=startF-2*unit; (*ge)(indexF, zero) && !connectedLeftTop; indexF=indexF-unit)
    if(connectedLeftTop = (it = inBottomRight.find(startE - unit)) != inBottomRight.end() &&
                          it->second.find(indexF) != it->second.end())
      return DRIGHT;
  connectedRightTop = false;
  for(int indexF=endF+2*unit; (*lt)(indexF, countF) && !connectedRightTop; indexF=indexF+unit)
    if(connectedRightTop = (it = inBottomLeft.find(startE - unit)) != inBottomLeft.end() &&
                           it->second.find(indexF) != it->second.end())
      return DLEFT;
  return UNKNOWN;
}

// to be called with countF-1 instead of countF
REO_POS getOrientHierModel (SentenceAlignment & sentence, REO_MODEL_TYPE modelType,
                            bool connectedLeftTop, bool connectedRightTop,
                            int startF, int endF, int startE, int endE, int countF, int zero, int unit,
                            bool (*ge)(int, int), bool (*lt)(int, int),
                            const HSentenceVertices & inBottomRight, const HSentenceVertices & inBottomLeft,
                            const HSentenceVertices & outBottomRight, const HSentenceVertices & outBottomLeft,
                            REO_POS phraseOrient)
{

  HSentenceVertices::const_iterator it;

  if(phraseOrient == LEFT ||
      (connectedLeftTop && !connectedRightTop) ||
      //    (startE == 0 && startF == 0) ||
      //(startE == sentence.target.size()-1 && startF == sentence.source.size()-1) ||
      ((it = inBottomRight.find(startE - unit)) != inBottomRight.end() &&
       it->second.find(startF-unit) != it->second.end()) ||
      ((it = outBottomRight.find(startE - unit)) != outBottomRight.end() &&
       it->second.find(startF-unit) != it->second.end()))
    return LEFT;
  if(modelType == REO_MONO)
    return UNKNOWN;
  if(phraseOrient == RIGHT ||
      (!connectedLeftTop &&  connectedRightTop) ||
      ((it = inBottomLeft.find(startE - unit)) != inBottomLeft.end() &&
       it->second.find(endF + unit) != it->second.end()) ||
      ((it = outBottomLeft.find(startE - unit)) != outBottomLeft.end() &&
       it->second.find(endF + unit) != it->second.end()))
    return RIGHT;
  if(modelType == REO_MSD)
    return UNKNOWN;
  if(phraseOrient != UNKNOWN)
    return phraseOrient;
  connectedLeftTop = false;
  for(int indexF=startF-2*unit; (*ge)(indexF, zero) && !connectedLeftTop; indexF=indexF-unit) {
    if((connectedLeftTop = (it = inBottomRight.find(startE - unit)) != inBottomRight.end() &&
                           it->second.find(indexF) != it->second.end()) ||
        (connectedLeftTop = (it = outBottomRight.find(startE - unit)) != outBottomRight.end() &&
                            it->second.find(indexF) != it->second.end()))
      return DRIGHT;
  }
  connectedRightTop = false;
  for(int indexF=endF+2*unit; (*lt)(indexF, countF) && !connectedRightTop; indexF=indexF+unit) {
    if((connectedRightTop = (it = inBottomLeft.find(startE - unit)) != inBottomLeft.end() &&
                            it->second.find(indexF) != it->second.end()) ||
        (connectedRightTop = (it = outBottomLeft.find(startE - unit)) != outBottomLeft.end() &&
                             it->second.find(indexF) != it->second.end()))
      return DLEFT;
  }
  return UNKNOWN;
}

bool isAligned ( SentenceAlignment &sentence, int fi, int ei )
{
  if (ei == -1 && fi == -1)
    return true;
  if (ei <= -1 || fi <= -1)
    return false;
  if ((size_t)ei == sentence.target.size() && (size_t)fi == sentence.source.size())
    return true;
  if ((size_t)ei >= sentence.target.size() || (size_t)fi >= sentence.source.size())
    return false;
  for(size_t i=0; i<sentence.alignedToT[ei].size(); i++)
    if (sentence.alignedToT[ei][i] == fi)
      return true;
  return false;
}

bool ge(int first, int second)
{
  return first >= second;
}

bool le(int first, int second)
{
  return first <= second;
}

bool lt(int first, int second)
{
  return first < second;
}

void insertVertex( HSentenceVertices & corners, int x, int y )
{
  set<int> tmp;
  tmp.insert(x);
  pair< HSentenceVertices::iterator, bool > ret = corners.insert( pair<int, set<int> > (y, tmp) );
  if(ret.second == false) {
    ret.first->second.insert(x);
  }
}

void insertPhraseVertices(
  HSentenceVertices & topLeft,
  HSentenceVertices & topRight,
  HSentenceVertices & bottomLeft,
  HSentenceVertices & bottomRight,
  int startF, int startE, int endF, int endE)
{

  insertVertex(topLeft, startF, startE);
  insertVertex(topRight, endF, startE);
  insertVertex(bottomLeft, startF, endE);
  insertVertex(bottomRight, endF, endE);
}

string getOrientString(REO_POS orient, REO_MODEL_TYPE modelType)
{
  switch(orient) {
  case LEFT:
    return "mono";
    break;
  case RIGHT:
    return "swap";
    break;
  case DRIGHT:
    return "dright";
    break;
  case DLEFT:
    return "dleft";
    break;
  case UNKNOWN:
    switch(modelType) {
    case REO_MONO:
      return "nomono";
      break;
    case REO_MSD:
      return "other";
      break;
    case REO_MSLR:
      return "dright";
      break;
    }
    break;
  }
  return "";
}

int getClass(const std::string &str)
{
	size_t pos = str.find("swap");
	if (pos == str.npos) {
		return 0;
	}
	else if (pos == 0) {
		return 1;
	}
	else {
		return 2;
	}
}

void ExtractTask::addPhrase( SentenceAlignment &sentence, int startE, int endE, int startF, int endF , string &orientationInfo)
{
  if (m_options.isOnlyOutputSpanInfo()) {
    cout << startF << " " << endF << " " << startE << " " << endE << endl;
    return;
  }

  const string &sep = m_options.separator;

  m_extractFileOrientation << sentence.sentenceID << " " << sep << " ";
  m_extractFileOrientation << getClass(orientationInfo) << " " << sep << " ";

  // position
  m_extractFileOrientation << startF << " " << endF << " " << sep << " ";

  // start
  m_extractFileOrientation << "<s> ";
  for(int fi=0; fi<startF; fi++) {
	  m_extractFileOrientation << sentence.source[fi] << " ";
  }
  m_extractFileOrientation << sep << " ";

  // middle
  for(int fi=startF; fi<=endF; fi++) {
	  m_extractFileOrientation << sentence.source[fi] << " ";
  }
  m_extractFileOrientation << sep << " ";

  // end
  for(int fi=endF+1; fi<sentence.source.size(); fi++) {
	  m_extractFileOrientation << sentence.source[fi] << " ";
  }
  m_extractFileOrientation << "</s> ";

  // target
  /*
  for(int ei=startE; ei<=endE; ei++) {
	  m_extractFileOrientation << sentence.target[ei] << " ";
  }
  */
  m_extractFileOrientation << endl;
}

/** tokenise input string to vector of string. each element has been separated by a character in the delimiters argument.
		The separator can only be 1 character long. The default delimiters are space or tab
*/
std::vector<std::string> Tokenize(const std::string& str,
                                  const std::string& delimiters)
{
  std::vector<std::string> tokens;
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  // Find first "non-delimiter".
  std::string::size_type pos     = str.find_first_of(delimiters, lastPos);

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

  return tokens;
}

}
<commit_msg>delete extract-ordering. Not part of the core functionality<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2017 Devin Matthews and Intel Corp.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdint>
#include <string>

#include <cpuid.h>

static std::string get_cpu_name()
{
    char cpu_name[48] = {};
    uint32_t eax, ebx, ecx, edx;

    __cpuid(0x80000002u, eax, ebx, ecx, edx);
    //printf("%x %x %x %x\n", eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[0]  = eax;
    *(uint32_t *)&cpu_name[4]  = ebx;
    *(uint32_t *)&cpu_name[8]  = ecx;
    *(uint32_t *)&cpu_name[12] = edx;

    __cpuid(0x80000003u, eax, ebx, ecx, edx);
    //printf("%x %x %x %x\n", eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[16+0]  = eax;
    *(uint32_t *)&cpu_name[16+4]  = ebx;
    *(uint32_t *)&cpu_name[16+8]  = ecx;
    *(uint32_t *)&cpu_name[16+12] = edx;

    __cpuid(0x80000004u, eax, ebx, ecx, edx);
    //printf("%x %x %x %x\n", eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[32+0]  = eax;
    *(uint32_t *)&cpu_name[32+4]  = ebx;
    *(uint32_t *)&cpu_name[32+8]  = ecx;
    *(uint32_t *)&cpu_name[32+12] = edx;

    return std::string(cpu_name);
}

int vpu_count()
{
    std::string name = get_cpu_name();

    return 2;

    if (name.find("Intel(R) Xeon(R)") != std::string::npos)
    {
        auto loc = name.find("Platinum");
        if (loc == std::string::npos) loc = name.find("Gold");
        if (loc == std::string::npos) loc = name.find("Silver");
        if (loc == std::string::npos) loc = name.find("Bronze");
        if (loc == std::string::npos) loc = name.find("W");
        if (loc == std::string::npos) return -1;

        auto sku = atoi(name.substr(loc+1, 4).c_str());
        if      (8199 >= sku && sku >= 8100) return 2;
        else if (6199 >= sku && sku >= 6100) return 2;
        else if (sku == 5122)                return 2;
        else if (5199 >= sku && sku >= 5100) return 1;
        else if (4199 >= sku && sku >= 4100) return 1;
        else if (3199 >= sku && sku >= 3100) return 1;
        else if (2199 >= sku && sku >= 2120) return 2;
        else if (2119 >= sku && sku >= 2100) return 1;
        else return -1;
    }
    else if (name.find("Intel(R) Core(TM) i9") != std::string::npos)
    {
        return 1;
    }
    else if (name.find("Intel(R) Core(TM) i7") != std::string::npos)
    {
        if (name.find("7800X") != std::string::npos ||
            name.find("7820X") != std::string::npos) return 1;
        else return -1;
    }
    else
    {
        return -1;
    }
}
<commit_msg>Fix vpu_count.<commit_after>/*
 * Copyright 2017 Devin Matthews and Intel Corp.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdint>
#include <string>

#include <cpuid.h>

static std::string get_cpu_name()
{
    char cpu_name[48] = {};
    uint32_t eax, ebx, ecx, edx;

    __cpuid(0x80000002u, eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[0]  = eax;
    *(uint32_t *)&cpu_name[4]  = ebx;
    *(uint32_t *)&cpu_name[8]  = ecx;
    *(uint32_t *)&cpu_name[12] = edx;

    __cpuid(0x80000003u, eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[16+0]  = eax;
    *(uint32_t *)&cpu_name[16+4]  = ebx;
    *(uint32_t *)&cpu_name[16+8]  = ecx;
    *(uint32_t *)&cpu_name[16+12] = edx;

    __cpuid(0x80000004u, eax, ebx, ecx, edx);

    *(uint32_t *)&cpu_name[32+0]  = eax;
    *(uint32_t *)&cpu_name[32+4]  = ebx;
    *(uint32_t *)&cpu_name[32+8]  = ecx;
    *(uint32_t *)&cpu_name[32+12] = edx;

    return std::string(cpu_name);
}

int vpu_count()
{
    std::string name = get_cpu_name();

    if (name.find("Intel(R) Xeon(R)") != std::string::npos)
    {
        auto loc = name.find("Platinum");
        if (loc == std::string::npos) loc = name.find("Gold");
        if (loc == std::string::npos) loc = name.find("Silver");
        if (loc == std::string::npos) loc = name.find("Bronze");
        if (loc == std::string::npos) loc = name.find("W");
        if (loc == std::string::npos) return -1;
        loc = name.find_first_of("- ", loc+1)+1;

        auto sku = atoi(name.substr(loc, 4).c_str());
        if      (8199 >= sku && sku >= 8100) return 2;
        else if (6199 >= sku && sku >= 6100) return 2;
        else if (sku == 5122)                return 2;
        else if (5199 >= sku && sku >= 5100) return 1;
        else if (4199 >= sku && sku >= 4100) return 1;
        else if (3199 >= sku && sku >= 3100) return 1;
        else if (2199 >= sku && sku >= 2120) return 2;
        else if (2119 >= sku && sku >= 2100) return 1;
        else return -1;
    }
    else if (name.find("Intel(R) Core(TM) i9") != std::string::npos)
    {
        return 2;
    }
    else if (name.find("Intel(R) Core(TM) i7") != std::string::npos)
    {
        if (name.find("7800X") != std::string::npos ||
            name.find("7820X") != std::string::npos) return 2;
        else return -1;
    }
    else
    {
        return -1;
    }
}
<|endoftext|>


<commit_before>/*
 *  WrapperIO.cpp
 *  This file is part of FRESteamWorks.
 *
 *  Created by Ventero <http://github.com/Ventero>
 *  Copyright (c) 2012-2014 Level Up Labs, LLC. All rights reserved.
 */

#include "WrapperIO.h"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <ios>
#include <iostream>
#include <iterator>
#include <sstream>

using namespace amf;

void sendData(Serializer& serializer) {
	std::vector<u8> data = serializer.data();
	if(data.size() > 1024) {
		// due to output buffering, large outputs need to be sent via a tempfile
		sendDataTempFile(serializer);
		return;
	}

	serializer.clear();

	// first, send a length prefix
	std::vector<u8> length = AmfInteger(data.size()).serialize();
	std::copy(length.begin(), length.end(), std::ostream_iterator<u8>(std::cout));
	// send actual data
	std::copy(data.begin(), data.end(), std::ostream_iterator<u8>(std::cout));
}

void sendDataTempFile(Serializer& serializer) {
	std::vector<u8> data = serializer.data();
	serializer.clear();

	// send length via stdout
	std::vector<u8> length = AmfInteger(data.size()).serialize();
	std::copy(length.begin(), length.end(), std::ostream_iterator<u8>(std::cout));

	std::string filename = std::tmpnam(nullptr);
	std::fstream tmpfile(filename, std::ios::out | std::ios::binary);
	std::copy(data.begin(), data.end(), std::ostream_iterator<u8>(tmpfile));
	tmpfile.close();
	send(filename);
}

void sendItem(const AmfItem& item) {
	Serializer serializer;
	serializer << item;
	sendData(serializer);
}

void send(bool value) {
	sendItem(AmfBool(value));
}

void send(int32 value) {
	sendItem(AmfInteger(value));
}

void send(uint32 value) {
	sendItem(AmfInteger(value));
}

void send(uint64 value) {
	sendItem(AmfString(std::to_string(value)));
}

void send(float value) {
	sendItem(AmfDouble(value));
}

void send(double value) {
	sendItem(AmfDouble(value));
}

void send(std::string value) {
	sendItem(AmfString(value));
}

void send(const AmfItem& value) {
	sendItem(value);
}

// sentinel for pseudo-void functions
void send(std::nullptr_t) { }

// TODO: replace this mess with AMF
bool get_bool() {
	std::string item;
	std::getline(std::cin, item);
	return item == "true";
}

int32 get_int() {
	std::string item;
	std::getline(std::cin, item);
	return std::stoi(item);
}

float get_float() {
	std::string item;
	std::getline(std::cin, item);
	return std::stof(item);
}

std::string get_string() {
	std::string item;
	std::getline(std::cin, item);

	size_t length = std::stoi(item);
	if (length < 1) return "";

	if (length > 1024)
		return readTempFileBuf(length);

	char* buf = new char[length];
	std::cin.read(buf, length);
	// remove trailing newline
	std::string result(buf, length - 1);

	delete[] buf;
	return result;
}

std::string get_bytearray() {
	std::string item;
	std::getline(std::cin, item);

	size_t length = std::stoi(item);
	if (length < 1) return "";
	return readTempFileBuf(length);
}

uint64 get_uint64() {
	std::string str = get_string();
	std::istringstream ss(str);

	uint64 val;
	if(!(ss >> val)) return 0;

	return val;
}

std::vector<std::string> get_string_array() {
	return get_array<std::string>(get_string);
}

std::string readTempFileBuf(size_t length) {
	std::string filename;
	std::getline(std::cin, filename);
	std::ifstream tempfile(filename, std::ios::in | std::ios::binary);

	char* buf = new char[length];
	tempfile.read(buf, length);

	std::string result(buf, length - 1);

	delete[] buf;
	tempfile.close();
	std::remove(filename.c_str());

	return result;
}
<commit_msg>Flush stdout after sending data.<commit_after>/*
 *  WrapperIO.cpp
 *  This file is part of FRESteamWorks.
 *
 *  Created by Ventero <http://github.com/Ventero>
 *  Copyright (c) 2012-2014 Level Up Labs, LLC. All rights reserved.
 */

#include "WrapperIO.h"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <ios>
#include <iostream>
#include <iterator>
#include <sstream>

using namespace amf;

void sendData(Serializer& serializer) {
	std::vector<u8> data = serializer.data();
	if(data.size() > 1024) {
		// due to output buffering, large outputs need to be sent via a tempfile
		sendDataTempFile(serializer);
		return;
	}

	serializer.clear();

	// first, send a length prefix
	std::vector<u8> length = AmfInteger(data.size()).serialize();
	std::copy(length.begin(), length.end(), std::ostream_iterator<u8>(std::cout));
	// send actual data
	std::copy(data.begin(), data.end(), std::ostream_iterator<u8>(std::cout));
	std::cout << std::flush;
}

void sendDataTempFile(Serializer& serializer) {
	std::vector<u8> data = serializer.data();
	serializer.clear();

	// send length via stdout
	std::vector<u8> length = AmfInteger(data.size()).serialize();
	std::copy(length.begin(), length.end(), std::ostream_iterator<u8>(std::cout));

	std::string filename = std::tmpnam(nullptr);
	std::fstream tmpfile(filename, std::ios::out | std::ios::binary);
	std::copy(data.begin(), data.end(), std::ostream_iterator<u8>(tmpfile));
	tmpfile.close();
	send(filename);
}

void sendItem(const AmfItem& item) {
	Serializer serializer;
	serializer << item;
	sendData(serializer);
}

void send(bool value) {
	sendItem(AmfBool(value));
}

void send(int32 value) {
	sendItem(AmfInteger(value));
}

void send(uint32 value) {
	sendItem(AmfInteger(value));
}

void send(uint64 value) {
	sendItem(AmfString(std::to_string(value)));
}

void send(float value) {
	sendItem(AmfDouble(value));
}

void send(double value) {
	sendItem(AmfDouble(value));
}

void send(std::string value) {
	sendItem(AmfString(value));
}

void send(const AmfItem& value) {
	sendItem(value);
}

// sentinel for pseudo-void functions
void send(std::nullptr_t) { }

// TODO: replace this mess with AMF
bool get_bool() {
	std::string item;
	std::getline(std::cin, item);
	return item == "true";
}

int32 get_int() {
	std::string item;
	std::getline(std::cin, item);
	return std::stoi(item);
}

float get_float() {
	std::string item;
	std::getline(std::cin, item);
	return std::stof(item);
}

std::string get_string() {
	std::string item;
	std::getline(std::cin, item);

	size_t length = std::stoi(item);
	if (length < 1) return "";

	if (length > 1024)
		return readTempFileBuf(length);

	char* buf = new char[length];
	std::cin.read(buf, length);
	// remove trailing newline
	std::string result(buf, length - 1);

	delete[] buf;
	return result;
}

std::string get_bytearray() {
	std::string item;
	std::getline(std::cin, item);

	size_t length = std::stoi(item);
	if (length < 1) return "";
	return readTempFileBuf(length);
}

uint64 get_uint64() {
	std::string str = get_string();
	std::istringstream ss(str);

	uint64 val;
	if(!(ss >> val)) return 0;

	return val;
}

std::vector<std::string> get_string_array() {
	return get_array<std::string>(get_string);
}

std::string readTempFileBuf(size_t length) {
	std::string filename;
	std::getline(std::cin, filename);
	std::ifstream tempfile(filename, std::ios::in | std::ios::binary);

	char* buf = new char[length];
	tempfile.read(buf, length);

	std::string result(buf, length - 1);

	delete[] buf;
	tempfile.close();
	std::remove(filename.c_str());

	return result;
}
<|endoftext|>


<commit_before>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * E133Receiver.cpp
 * Copyright (C) 2011 Simon Newton
 */

#include <ola/Callback.h>
#include <ola/Logging.h>
#include <ola/network/IPV4Address.h>
#include <ola/rdm/RDMCommand.h>
#include <ola/rdm/RDMHelper.h>

#include <string>
#include <vector>

#include "plugins/e131/e131/E133Header.h"
#include "plugins/e131/e131/DMPAddress.h"
#include "plugins/e131/e131/E133Layer.h"

#include "E133Receiver.h"

using ola::plugin::e131::DMPAddressData;
using ola::plugin::e131::E133Header;
using ola::plugin::e131::TwoByteRangeDMPAddress;
using ola::rdm::RDMRequest;

E133Receiver::E133Receiver(unsigned int universe,
                           ola::rdm::RDMControllerInterface *local_controller)
    : m_e133_layer(NULL),
      m_local_controller(local_controller),
      m_universe(universe) {
  if (!universe)
    OLA_FATAL <<
      "E133Receiver created with universe 0, this isn't valid";
}

/**
 * Check for requests that have timed out
 */
void E133Receiver::CheckForStaleRequests(const ola::TimeStamp *now) {
  (void) now;
}

/**
 * Handle a RDM response addressed to this universe
 */
void E133Receiver::HandlePacket(
    const ola::plugin::e131::TransportHeader &transport_header,
    const ola::plugin::e131::E133Header &e133_header,
    const std::string &raw_request) {
  OLA_INFO << "Got data from " << transport_header.SourceIP() <<
    " for universe " << e133_header.Universe();

  // attempt to unpack as a request
  const ola::rdm::RDMRequest *request = ola::rdm::RDMRequest::InflateFromData(
    reinterpret_cast<const uint8_t*>(raw_request.data()),
    raw_request.size());

  if (!request) {
    OLA_WARN << "Failed to unpack E1.33 RDM message, ignoring request.";
    return;
  }

  m_local_controller->SendRDMRequest(
      request,
      ola::NewSingleCallback(this,
                             &E133Receiver::RequestComplete,
                             transport_header.SourceIP(),
                             transport_header.SourcePort(),
                             e133_header.Sequence()));
}

/**
 * Handle a completed RDM request
 */
void E133Receiver::RequestComplete(ola::network::IPV4Address src_ip,
                                   uint16_t src_port,
                                   uint8_t sequence_number,
                                   ola::rdm::rdm_response_code response_code,
                                   const ola::rdm::RDMResponse *response,
                                   const std::vector<std::string> &packets) {
  if (response_code != ola::rdm::RDM_COMPLETED_OK) {
    OLA_WARN << "E1.33 request failed with code " <<
      ola::rdm::ResponseCodeToString(response_code) <<
      ", dropping request";
  }

  OLA_INFO << "rdm size is " << response->Size();

  // TODO(simon): handle the ack overflow case here
  // For now we just send back one packet.
  unsigned int actual_size = response->Size();
  uint8_t *rdm_data = new uint8_t[actual_size + 1];
  rdm_data[0] = ola::rdm::RDMCommand::START_CODE;

  if (!response->Pack(rdm_data + 1, &actual_size)) {
    OLA_WARN << "Failed to pack RDM response, aborting send";
    delete[] rdm_data;
    return;
  }
  unsigned int rdm_data_size = actual_size + 1;

  ola::plugin::e131::TwoByteRangeDMPAddress range_addr(0,
                                                       1,
                                                       rdm_data_size);
  ola::plugin::e131::DMPAddressData<
    ola::plugin::e131::TwoByteRangeDMPAddress> range_chunk(
        &range_addr,
        rdm_data,
        rdm_data_size);
  std::vector<DMPAddressData<TwoByteRangeDMPAddress> > ranged_chunks;
  ranged_chunks.push_back(range_chunk);
  const ola::plugin::e131::DMPPDU *pdu =
    ola::plugin::e131::NewRangeDMPSetProperty<uint16_t>(
        true,
        false,
        ranged_chunks);

  E133Header header("foo bar",
                    100,
                    sequence_number,
                    m_universe,
                    false,  // management
                    false);  // squawk

  bool result = m_e133_layer->SendDMP(header, pdu, src_ip, src_port);
  if (!result)
    OLA_WARN << "Failed to send E1.33 response";

  // send response back to src ip:port with correct seq #
  delete[] rdm_data;
  delete pdu;

  if (response)
    delete response;

  (void) src_port;
  (void) packets;
}
<commit_msg> * e133: handle the broad/vendorcast case in the receiver<commit_after>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * E133Receiver.cpp
 * Copyright (C) 2011 Simon Newton
 */

#include <ola/Callback.h>
#include <ola/Logging.h>
#include <ola/network/IPV4Address.h>
#include <ola/rdm/RDMCommand.h>
#include <ola/rdm/RDMHelper.h>

#include <string>
#include <vector>

#include "plugins/e131/e131/E133Header.h"
#include "plugins/e131/e131/DMPAddress.h"
#include "plugins/e131/e131/E133Layer.h"

#include "E133Receiver.h"

using ola::plugin::e131::DMPAddressData;
using ola::plugin::e131::E133Header;
using ola::plugin::e131::TwoByteRangeDMPAddress;
using ola::rdm::RDMRequest;

E133Receiver::E133Receiver(unsigned int universe,
                           ola::rdm::RDMControllerInterface *local_controller)
    : m_e133_layer(NULL),
      m_local_controller(local_controller),
      m_universe(universe) {
  if (!universe)
    OLA_FATAL <<
      "E133Receiver created with universe 0, this isn't valid";
}

/**
 * Check for requests that have timed out
 */
void E133Receiver::CheckForStaleRequests(const ola::TimeStamp *now) {
  (void) now;
}

/**
 * Handle a RDM response addressed to this universe
 */
void E133Receiver::HandlePacket(
    const ola::plugin::e131::TransportHeader &transport_header,
    const ola::plugin::e131::E133Header &e133_header,
    const std::string &raw_request) {
  OLA_INFO << "Got data from " << transport_header.SourceIP() <<
    " for universe " << e133_header.Universe();

  // attempt to unpack as a request
  const ola::rdm::RDMRequest *request = ola::rdm::RDMRequest::InflateFromData(
    reinterpret_cast<const uint8_t*>(raw_request.data()),
    raw_request.size());

  if (!request) {
    OLA_WARN << "Failed to unpack E1.33 RDM message, ignoring request.";
    return;
  }

  m_local_controller->SendRDMRequest(
      request,
      ola::NewSingleCallback(this,
                             &E133Receiver::RequestComplete,
                             transport_header.SourceIP(),
                             transport_header.SourcePort(),
                             e133_header.Sequence()));
}

/**
 * Handle a completed RDM request
 */
void E133Receiver::RequestComplete(ola::network::IPV4Address src_ip,
                                   uint16_t src_port,
                                   uint8_t sequence_number,
                                   ola::rdm::rdm_response_code response_code,
                                   const ola::rdm::RDMResponse *response,
                                   const std::vector<std::string> &packets) {
  if (response_code != ola::rdm::RDM_COMPLETED_OK) {
    OLA_WARN << "E1.33 request failed with code " <<
      ola::rdm::ResponseCodeToString(response_code) <<
      ", dropping request";
    delete response;
    return;
  }

  OLA_INFO << "rdm size is " << response->Size();

  // TODO(simon): handle the ack overflow case here
  // For now we just send back one packet.
  unsigned int actual_size = response->Size();
  uint8_t *rdm_data = new uint8_t[actual_size + 1];
  rdm_data[0] = ola::rdm::RDMCommand::START_CODE;

  if (!response->Pack(rdm_data + 1, &actual_size)) {
    OLA_WARN << "Failed to pack RDM response, aborting send";
    delete[] rdm_data;
    return;
  }
  unsigned int rdm_data_size = actual_size + 1;

  ola::plugin::e131::TwoByteRangeDMPAddress range_addr(0,
                                                       1,
                                                       rdm_data_size);
  ola::plugin::e131::DMPAddressData<
    ola::plugin::e131::TwoByteRangeDMPAddress> range_chunk(
        &range_addr,
        rdm_data,
        rdm_data_size);
  std::vector<DMPAddressData<TwoByteRangeDMPAddress> > ranged_chunks;
  ranged_chunks.push_back(range_chunk);
  const ola::plugin::e131::DMPPDU *pdu =
    ola::plugin::e131::NewRangeDMPSetProperty<uint16_t>(
        true,
        false,
        ranged_chunks);

  E133Header header("foo bar",
                    100,
                    sequence_number,
                    m_universe,
                    false,  // management
                    false);  // squawk

  bool result = m_e133_layer->SendDMP(header, pdu, src_ip, src_port);
  if (!result)
    OLA_WARN << "Failed to send E1.33 response";

  // send response back to src ip:port with correct seq #
  delete[] rdm_data;
  delete pdu;

  if (response)
    delete response;

  (void) src_port;
  (void) packets;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/feature_kv_iterator.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.hpp>

namespace boost { namespace spirit { namespace traits {

template <>
struct is_container<mapnik::Feature const> : mpl::false_ {} ;

template <>
struct container_iterator<mapnik::Feature const>
{
    typedef mapnik::feature_kv_iterator2 type;
};

template <>
struct begin_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.begin(),f.end());
    }
};

template <>
struct end_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.end(),f.end());
    }
};

template <>
struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>,
                           mapnik::geometry_container const& ,karma::domain>
{
    typedef mapnik::geometry_container const& type;
    static type pre(const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>& f)
    {
        return boost::fusion::at<mpl::int_<0> >(f).paths();
    }
};

}}}

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

struct get_id
{
    template <typename T>
    struct result { typedef int type; };

    int operator() (mapnik::Feature const& f) const
    {
        return f.id();
    }
};

struct make_properties_range
{
    typedef boost::iterator_range<mapnik::feature_kv_iterator> properties_range_type;

    template <typename T>
    struct result { typedef properties_range_type type; };

    properties_range_type operator() (mapnik::Feature const& f) const
    {
        return boost::make_iterator_range(f.begin(),f.end());
    }
};

struct utf8
{
    template <typename T>
    struct result { typedef std::string type; };

    std::string operator() (UnicodeString const& ustr) const
    {
        std::string result;
        to_utf8(ustr,result);
        return result;
    }
};

struct value_base
{
    template <typename T>
    struct result { typedef mapnik::value_base const& type; };

    mapnik::value_base const& operator() (mapnik::value const& val) const
    {
        return val.base();
    }
};

template <typename OutputIterator>
struct escaped_string
    : karma::grammar<OutputIterator, std::string(char const*)>
{
    escaped_string()
        : escaped_string::base_type(esc_str)
    {
        using boost::spirit::karma::maxwidth;
        using boost::spirit::karma::right_align;

        esc_char.add('\a', "\\a")('\b', "\\b")('\f', "\\f")('\n', "\\n")
            ('\r', "\\r")('\t', "\\t")('\v', "\\v")('\\', "\\\\")
            ('\'', "\\\'")('\"', "\\\"")
            ;

        esc_str =   karma::lit(karma::_r1)
            << *(esc_char
                 | karma::print
                 | "\\u" << right_align(4,karma::lit('0'))[karma::hex])
            <<  karma::lit(karma::_r1)
            ;
    }

    karma::rule<OutputIterator, std::string(char const*)> esc_str;
    karma::symbols<char, char const*> esc_char;

};

template <typename OutputIterator>
struct feature_generator_grammar:
        karma::grammar<OutputIterator, mapnik::Feature const&()>
{
    typedef boost::tuple<std::string, mapnik::value> pair_type;
    typedef make_properties_range::properties_range_type range_type;

    feature_generator_grammar()
        : feature_generator_grammar::base_type(feature)
        , quote_("\"")

    {
        using boost::spirit::karma::lit;
        using boost::spirit::karma::uint_;
        using boost::spirit::karma::bool_;
        using boost::spirit::karma::int_;
        using boost::spirit::karma::double_;
        using boost::spirit::karma::_val;
        using boost::spirit::karma::_1;
        using boost::spirit::karma::_r1;
        using boost::spirit::karma::string;
        using boost::spirit::karma::eps;

        feature = lit("{\"type\":\"Feature\",\"id\":")
            << uint_[_1 = id_(_val)]
            << lit(",\"geometry\":") << geometry
            << lit(",\"properties\":") << properties
            << lit('}')
            ;

        properties = lit('{')
            << pair % lit(',')
            << lit('}')
            ;

        pair = lit('"')
            << string[_1 = phoenix::at_c<0>(_val)] << lit('"')
            << lit(':')
            << value(phoenix::at_c<1>(_val))
            ;

        value = (value_null_| bool_ | int_| double_ | ustring)[_1 = value_base_(_r1)]
            ;

        value_null_ = string[_1 = "null"]
            ;

        ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
            ;
    }

    // rules
    karma::rule<OutputIterator, mapnik::Feature const&()> feature;
    multi_geometry_generator_grammar<OutputIterator> geometry;
    escaped_string<OutputIterator> escaped_string_;
    karma::rule<OutputIterator, mapnik::Feature const&()> properties;
    karma::rule<OutputIterator, pair_type()> pair;
    karma::rule<OutputIterator, void(mapnik::value const&)> value;
    karma::rule<OutputIterator, mapnik::value_null()> value_null_;
    karma::rule<OutputIterator, UnicodeString()> ustring;
    // phoenix functions
    phoenix::function<get_id> id_;
    phoenix::function<value_base> value_base_;
    phoenix::function<utf8> utf8_;
    std::string quote_;
};

}}

#endif // MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
<commit_msg>+ geojson generator : allow empty properties<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/feature_kv_iterator.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.hpp>

namespace boost { namespace spirit { namespace traits {

template <>
struct is_container<mapnik::Feature const> : mpl::false_ {} ;

template <>
struct container_iterator<mapnik::Feature const>
{
    typedef mapnik::feature_kv_iterator2 type;
};

template <>
struct begin_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.begin(),f.end());
    }
};

template <>
struct end_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.end(),f.end());
    }
};

template <>
struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>,
                           mapnik::geometry_container const& ,karma::domain>
{
    typedef mapnik::geometry_container const& type;
    static type pre(const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>& f)
    {
        return boost::fusion::at<mpl::int_<0> >(f).paths();
    }
};

}}}

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

struct get_id
{
    template <typename T>
    struct result { typedef int type; };

    int operator() (mapnik::Feature const& f) const
    {
        return f.id();
    }
};

struct make_properties_range
{
    typedef boost::iterator_range<mapnik::feature_kv_iterator> properties_range_type;

    template <typename T>
    struct result { typedef properties_range_type type; };

    properties_range_type operator() (mapnik::Feature const& f) const
    {
        return boost::make_iterator_range(f.begin(),f.end());
    }
};

struct utf8
{
    template <typename T>
    struct result { typedef std::string type; };

    std::string operator() (UnicodeString const& ustr) const
    {
        std::string result;
        to_utf8(ustr,result);
        return result;
    }
};

struct value_base
{
    template <typename T>
    struct result { typedef mapnik::value_base const& type; };

    mapnik::value_base const& operator() (mapnik::value const& val) const
    {
        return val.base();
    }
};

template <typename OutputIterator>
struct escaped_string
    : karma::grammar<OutputIterator, std::string(char const*)>
{
    escaped_string()
        : escaped_string::base_type(esc_str)
    {
        using boost::spirit::karma::maxwidth;
        using boost::spirit::karma::right_align;

        esc_char.add('\a', "\\a")('\b', "\\b")('\f', "\\f")('\n', "\\n")
            ('\r', "\\r")('\t', "\\t")('\v', "\\v")('\\', "\\\\")
            ('\'', "\\\'")('\"', "\\\"")
            ;

        esc_str =   karma::lit(karma::_r1)
            << *(esc_char
                 | karma::print
                 | "\\u" << right_align(4,karma::lit('0'))[karma::hex])
            <<  karma::lit(karma::_r1)
            ;
    }

    karma::rule<OutputIterator, std::string(char const*)> esc_str;
    karma::symbols<char, char const*> esc_char;

};

template <typename OutputIterator>
struct feature_generator_grammar:
        karma::grammar<OutputIterator, mapnik::Feature const&()>
{
    typedef boost::tuple<std::string, mapnik::value> pair_type;
    typedef make_properties_range::properties_range_type range_type;

    feature_generator_grammar()
        : feature_generator_grammar::base_type(feature)
        , quote_("\"")

    {
        using boost::spirit::karma::lit;
        using boost::spirit::karma::uint_;
        using boost::spirit::karma::bool_;
        using boost::spirit::karma::int_;
        using boost::spirit::karma::double_;
        using boost::spirit::karma::_val;
        using boost::spirit::karma::_1;
        using boost::spirit::karma::_r1;
        using boost::spirit::karma::string;
        using boost::spirit::karma::eps;

        feature = lit("{\"type\":\"Feature\",\"id\":")
            << uint_[_1 = id_(_val)]
            << lit(",\"geometry\":") << geometry
            << lit(",\"properties\":") << properties
            << lit('}')
            ;

        properties = lit('{')
            << -(pair % lit(','))
            << lit('}')
            ;

        pair = lit('"')
            << string[_1 = phoenix::at_c<0>(_val)] << lit('"')
            << lit(':')
            << value(phoenix::at_c<1>(_val))
            ;

        value = (value_null_| bool_ | int_| double_ | ustring)[_1 = value_base_(_r1)]
            ;

        value_null_ = string[_1 = "null"]
            ;

        ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
            ;
    }

    // rules
    karma::rule<OutputIterator, mapnik::Feature const&()> feature;
    multi_geometry_generator_grammar<OutputIterator> geometry;
    escaped_string<OutputIterator> escaped_string_;
    karma::rule<OutputIterator, mapnik::Feature const&()> properties;
    karma::rule<OutputIterator, pair_type()> pair;
    karma::rule<OutputIterator, void(mapnik::value const&)> value;
    karma::rule<OutputIterator, mapnik::value_null()> value_null_;
    karma::rule<OutputIterator, UnicodeString()> ustring;
    // phoenix functions
    phoenix::function<get_id> id_;
    phoenix::function<value_base> value_base_;
    phoenix::function<utf8> utf8_;
    std::string quote_;
};

}}

#endif // MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
<|endoftext|>


<commit_before>// Important do not use this FilterTask for final Filtered AOD productions!
// Due to the variability of the used config file, it is to easy to loose track of the used settings!

AliAnalysisTask *AddTask_pdill_JPsiFilter_PbPb(
  TString cfg="ConfigJpsi_nano_PbPb2015.C",
  Bool_t gridconf=kFALSE,
  TString period="",
  Bool_t storeLS = kFALSE,
  Bool_t hasMC_aod = kFALSE,
  ULong64_t triggers=AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral+AliVEvent::kEMCEGA+AliVEvent::kEMCEJE
  ){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskJPSIFilter", "No analysis manager found.");
    return 0;
  }

  //check for output aod handler
  if (!mgr->GetOutputEventHandler()||mgr->GetOutputEventHandler()->IsA()!=AliAODHandler::Class()) {
    Warning("AddTaskJPSIFilter","No AOD output handler available. Not adding the task!");
    return 0;
  }

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0)||hasMC_aod;

  //Do we run on AOD?
  Bool_t isAOD=mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();

  //Allow merging of the filtered aods on grid trains
  if(mgr->GetGridHandler()) {
    printf(" SET MERGE FILTERED AODs \n");
    //mgr->GetGridHandler()->SetMergeAOD(kTRUE);
  }

  TString configFile("");
  printf("pwd:        %s \n",gSystem->pwd());
  if(cfg.IsNull()) cfg="ConfigJpsi_nano_PbPb2015.C";

  TString alienPath("alien:///alice/cern.ch/user/p/pdillens/PWGDQ/dielectron/macrosJPSI/");
  TString alirootPath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosJPSI/");

  ////////// >>>>>>>>>> alien config
  if(gridconf) {
    if(!gSystem->Exec(Form("alien_cp %s/%s .",alienPath.Data(),cfg.Data()))) {
      gSystem->Exec(Form("ls -l %s",gSystem->pwd()));
      configFile=gSystem->pwd();
    }
    else {
      printf("ERROR: couldn't copy file %s/%s from grid \n", alienPath.Data(),cfg.Data() );
      return;
    }
  }
  ///////// >>>>>>>>> aliroot config
  else if(!gridconf) configFile=alirootPath.Data();
  ///////// add config to path
  configFile+="/";
  configFile+=cfg.Data();

  //load dielectron configuration file (only once)
  TString checkconfig="ConfigJpsi_nano_PbPb2015";
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(checkconfig.Data()))
    gROOT->LoadMacro(configFile.Data());

  AliDielectron *jpsi=ConfigJpsi_nano_PbPb2015(0,hasMC,period);

  if(isAOD) {
    //add options to AliAODHandler to duplicate input event
    AliAODHandler *aodHandler = (AliAODHandler*)mgr->GetOutputEventHandler();
    aodHandler->SetCreateNonStandardAOD();
    aodHandler->SetNeedsHeaderReplication();

   if(!period.Contains("LHC10h")) aodHandler->SetNeedsTOFHeaderReplication();
    aodHandler->SetNeedsVZEROReplication();
    /*aodHandler->SetNeedsTracksBranchReplication();
    aodHandler->SetNeedsCaloClustersBranchReplication();
    aodHandler->SetNeedsVerticesBranchReplication();
    aodHandler->SetNeedsCascadesBranchReplication();
    aodHandler->SetNeedsTrackletsBranchReplication();
    aodHandler->SetNeedsPMDClustersBranchReplication();
    aodHandler->SetNeedsJetsBranchReplication();
    aodHandler->SetNeedsFMDClustersBranchReplication();
    //aodHandler->SetNeedsMCParticlesBranchReplication();
    aodHandler->SetNeedsDimuonsBranchReplication();*/
    //    if(hasMC) aodHandler->SetNeedsV0sBranchReplication();
    if(hasMC) aodHandler->SetNeedsMCParticlesBranchReplication();
    jpsi->SetHasMC(hasMC);
  }

  //Create task and add it to the analysis manager
  AliAnalysisTaskDielectronFilter *task=new AliAnalysisTaskDielectronFilter("jpsi_DielectronFilter");
  task->SetTriggerMask(triggers);
  //  task->SetTriggerMask(AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral);
  if (!hasMC) task->UsePhysicsSelection();

  //   //Add event filter
  //   AliDielectronEventCuts *eventCuts=new AliDielectronEventCuts("eventCuts","Vertex Track && |vtxZ|<10 && ncontrib>0");
  //   if(!hasMC) eventCuts->SetRequireVertex();
  //   if (isAOD) eventCuts->SetVertexType(AliDielectronEventCuts::kVtxAny);
  //   eventCuts->SetMinVtxContributors(1);
  //   eventCuts->SetVertexZ(-10.,10.);
  //   eventCuts->SetCentralityRange(0.0,90.0);
  //   task->SetEventFilter(eventCuts);

  task->SetDielectron(jpsi);
  if(storeLS) task->SetStoreLikeSignCandidates(storeLS);
  task->SetCreateNanoAODs(kTRUE);
  task->SetStoreEventsWithSingleTracks(kTRUE);
  //task->SetStoreHeader(kTRUE);
  mgr->AddTask(task);

  //----------------------
  //create data containers
  //----------------------

  TString containerName = mgr->GetCommonFileName();
  containerName += ":PWGDQ_dielectronFilter";

  //create output container

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("jpsi_FilterQA",
                         THashList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer("jpsi_FilterEventStat",
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, mgr->GetCommonOutputContainer());
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);

  return task;
}
<commit_msg>DQ update PbPb filter AddTask<commit_after>// Important do not use this FilterTask for final Filtered AOD productions!
// Due to the variability of the used config file, it is to easy to loose track of the used settings!

AliAnalysisTask *AddTask_pdill_JPsiFilter_PbPb(
    TString cfg="ConfigJpsi_nano_PbPb2015.C",
    Bool_t gridconf=kFALSE,
    TString period="",
    Bool_t storeLS = kFALSE,
    Bool_t hasMC_aod = kFALSE,
    ULong64_t triggers = AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral+AliVEvent::kEMCEGA+AliVEvent::kEMCEJE
  ){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskJPSIFilter", "No analysis manager found.");
    return 0;
  }

  //check for output aod handler
  if (!mgr->GetOutputEventHandler()||mgr->GetOutputEventHandler()->IsA()!=AliAODHandler::Class()) {
    Warning("AddTaskJPSIFilter","No AOD output handler available. Not adding the task!");
    return 0;
  }

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0)||hasMC_aod;

  //Do we run on AOD?
  Bool_t isAOD=mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();

  //Allow merging of the filtered aods on grid trains
  if(mgr->GetGridHandler()) {
    printf(" SET MERGE FILTERED AODs \n");
    //mgr->GetGridHandler()->SetMergeAOD(kTRUE);
  }

  TString configFile("");
  printf("pwd:        %s \n",gSystem->pwd());
  if(cfg.IsNull()) cfg="ConfigJpsi_nano_PbPb2015.C";

  TString alienPath("alien:///alice/cern.ch/user/p/pdillens/PWGDQ/dielectron/macrosJPSI/");
  TString alirootPath("$ALICE_PHYSICS/PWGDQ/dielectron/macrosJPSI/");

  ////////// >>>>>>>>>> alien config
  if(gridconf) {
    if(!gSystem->Exec(Form("alien_cp %s/%s .",alienPath.Data(),cfg.Data()))) {
      gSystem->Exec(Form("ls -l %s",gSystem->pwd()));
      configFile=gSystem->pwd();
    }
    else {
      printf("ERROR: couldn't copy file %s/%s from grid \n", alienPath.Data(),cfg.Data() );
      return;
    }
  }
  ///////// >>>>>>>>> aliroot config
  else if(!gridconf) configFile=alirootPath.Data();
  ///////// add config to path
  //configFile+="/";
  configFile+=cfg.Data();

  //load dielectron configuration file (only once)
  TString checkconfig="ConfigJpsi_nano_PbPb2015";
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(checkconfig.Data()))
    gROOT->LoadMacro(configFile.Data());
    printf("%s \n",configFile.Data());

  AliDielectron *jpsi=ConfigJpsi_nano_PbPb2015(0,hasMC,period);

  if(isAOD) {
    //add options to AliAODHandler to duplicate input event
    AliAODHandler *aodHandler = (AliAODHandler*)mgr->GetOutputEventHandler();
    aodHandler->SetCreateNonStandardAOD();
    aodHandler->SetNeedsHeaderReplication();

   if(!period.Contains("LHC10h")) aodHandler->SetNeedsTOFHeaderReplication();
    aodHandler->SetNeedsVZEROReplication();
    // aodHandler->SetNeedsTracksBranchReplication();
    // aodHandler->SetNeedsCaloClustersBranchReplication();
    // aodHandler->SetNeedsVerticesBranchReplication();
    // aodHandler->SetNeedsCascadesBranchReplication();
    // aodHandler->SetNeedsTrackletsBranchReplication();
    // aodHandler->SetNeedsPMDClustersBranchReplication();
    // aodHandler->SetNeedsJetsBranchReplication();
    // aodHandler->SetNeedsFMDClustersBranchReplication();
    // aodHandler->SetNeedsMCParticlesBranchReplication();
    // aodHandler->SetNeedsDimuonsBranchReplication();
    if(hasMC) aodHandler->SetNeedsV0sBranchReplication();
    if(hasMC) aodHandler->SetNeedsMCParticlesBranchReplication();
    jpsi->SetHasMC(hasMC);
  }

  //Create task and add it to the analysis manager
  AliAnalysisTaskDielectronFilter *task=new AliAnalysisTaskDielectronFilter("jpsi_DielectronFilter");
  task->SetTriggerMask(triggers);
  //  task->SetTriggerMask(AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral);
  if (!hasMC) task->UsePhysicsSelection();

  //   //Add event filter
  //   AliDielectronEventCuts *eventCuts=new AliDielectronEventCuts("eventCuts","Vertex Track && |vtxZ|<10 && ncontrib>0");
  //   if(!hasMC) eventCuts->SetRequireVertex();
  //   if (isAOD) eventCuts->SetVertexType(AliDielectronEventCuts::kVtxAny);
  //   eventCuts->SetMinVtxContributors(1);
  //   eventCuts->SetVertexZ(-10.,10.);
  //   eventCuts->SetCentralityRange(0.0,90.0);
  //   task->SetEventFilter(eventCuts);

  task->SetDielectron(jpsi);
  if(storeLS) task->SetStoreLikeSignCandidates(storeLS);
  task->SetCreateNanoAODs(kTRUE);
  task->SetStoreEventsWithSingleTracks(kTRUE);
  task->SetStoreHeader(kTRUE);
  task->SetStoreEventplanes(kTRUE);

  mgr->AddTask(task);

  //----------------------
  //create data containers
  //----------------------

  TString containerName = mgr->GetCommonFileName();
  containerName += ":PWGDQ_dielectronFilter";

  //create output container

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("jpsi_FilterQA",
                         THashList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer("jpsi_FilterEventStat",
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, mgr->GetCommonOutputContainer());
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);

  return task;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objshimp.hxx,v $
 *
 *  $Revision: 1.39 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-21 16:50:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFX_OBJSHIMP_HXX
#define _SFX_OBJSHIMP_HXX

//#include <hash_map>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _DATETIME_HXX
#include <tools/datetime.hxx>
#endif

#include <svtools/securityoptions.hxx>
#include <sfx2/objsh.hxx>
#include "sfx2/docmacromode.hxx"
#include "bitset.hxx"

namespace svtools { class AsynchronLink; }

//====================================================================

DBG_NAMEEX(SfxObjectShell)

class SfxViewFrame;
struct MarkData_Impl
{
    String aMark;
    String aUserData;
    SfxViewFrame* pFrame;
};

class SfxFrame;
class SfxToolBoxConfig;
class SfxAcceleratorManager;
class SfxBasicManagerHolder;
struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess
{
    ::comphelper::EmbeddedObjectContainer* mpObjectContainer;
    SfxAcceleratorManager*  pAccMgr;
    SfxDocumentInfo*    pDocInfo;
    SfxConfigManager*   pCfgMgr;
    SfxBasicManagerHolder*
                        pBasicManager;
    SfxObjectShell&     rDocShell;
    ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
                        xBasicLibraries;
    ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
                        xDialogLibraries;
    ::sfx2::DocumentMacroMode
                        aMacroMode;
    SfxProgress*        pProgress;
    String              aTitle;
    String              aTempName;
    DateTime            nTime;
    sal_uInt16          nVisualDocumentNumber;
    sal_Int16           nDocumentSignatureState;
    sal_Int16           nScriptingSignatureState;
    sal_Bool            bTemplateConfig:1,
                        bInList:1,          // ob per First/Next erreichbar
                        bClosing:1,         // sal_True w"aehrend Close(), um Benachrichtigungs-Rekursionen zu verhindern
                        bSetInPlaceObj:1,   // sal_True, falls bereits versucht wurde pInPlaceObject zu casten
                        bIsSaving:1,
                        bPasswd:1,
                        bIsTmp:1,
                        bIsNamedVisible:1,
                        bIsTemplate:1,
                        bIsAbortingImport:1,  // Importvorgang soll abgebrochen werden.
                        bImportDone : 1, //Import schon fertig? Fuer AutoReload von Docs.
                        bInPrepareClose : 1,
                        bPreparedForClose : 1,
                        bWaitingForPicklist : 1,// Muss noch in die Pickliste
                        bModuleSearched : 1,
                        bIsBasicDefault : 1,
                        bIsHelpObjSh : 1,
                        bForbidCaching : 1,
                        bForbidReload : 1,
                        bSupportsEventMacros: 1,
                        bLoadingWindows: 1,
                        bBasicInitialized :1,
                        //bHidden :1, // indicates a hidden view shell
                        bIsPrintJobCancelable :1, // Stampit disable/enable cancel button for print jobs ... default = true = enable!
                        bOwnsStorage:1,
                        bNoBaseURL:1,
                        bInitialized:1,
                        bSignatureErrorIsShown:1,
                        bModelInitialized:1, // whether the related model is initialized
                        bPreserveVersions:1,
                        m_bMacroSignBroken:1, // whether the macro signature was explicitly broken
                        m_bNoBasicCapabilities:1,
                        bQueryLoadTemplate:1,
                        bLoadReadonly:1,
                        bUseUserData:1,
                        bSaveVersionOnClose:1;

    String              aNewName;  // Der Name, unter dem das Doc gespeichert
                                   // werden soll
    IndexBitSet         aBitSet;
    sal_uInt32               lErr;
    sal_uInt16              nEventId;           // falls vor Activate noch ein
                                            // Open/Create gesendet werden mu/s
    sal_Bool                bDoNotTouchDocInfo;

    AutoReloadTimer_Impl *pReloadTimer;
    MarkData_Impl*      pMarkData;
    sal_uInt16              nLoadedFlags;
    sal_uInt16              nFlagsInProgress;
    String              aMark;
    Size                aViewSize;          // wird leider vom Writer beim
    sal_Bool                bInFrame;           // HTML-Import gebraucht
    sal_Bool                bModalMode;
    sal_Bool                bRunningMacro;
    sal_Bool                bReloadAvailable;
    sal_uInt16              nAutoLoadLocks;
    SfxModule*              pModule;
    SfxFrame*               pFrame;
    SfxToolBoxConfig*       pTbxConfig;
    SfxEventConfigItem_Impl* pEventConfig;
    SfxObjectShellFlags     eFlags;
    svtools::AsynchronLink* pCloser;
    String                  aBaseURL;
    sal_Bool                bReadOnlyUI;
    SvRefBaseRef            xHeaderAttributes;
    sal_Bool                bHiddenLockedByAPI;
    sal_Bool                bInCloseEvent;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel;
    sal_uInt16              nStyleFilter;
    sal_Bool                bDisposing;

    sal_Bool                m_bEnableSetModified;
    sal_Bool                m_bIsModified;

    Rectangle               m_aVisArea;
    MapUnit                 m_nMapUnit;

    sal_Bool                m_bCreateTempStor;
    ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xDocStorage;

    sal_Bool                m_bIsInit;

    SfxObjectShell_Impl( SfxObjectShell& _rDocShell );
    virtual ~SfxObjectShell_Impl();

    // IMacroDocumentAccess overridables
    virtual sal_Int16 getImposedMacroExecMode() const;
    virtual ::rtl::OUString getDocumentLocation() const;
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getLastCommitDocumentStorage();
    virtual bool documentStorageHasMacros() const;
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const;
    virtual sal_Int16 getScriptingSignatureState() const;
    virtual void showBrokenSignatureWarning( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxInteraction ) const;
};

#endif

<commit_msg>INTEGRATION: CWS fwk80_SRC680 (1.39.16); FILE MERGED 2008/01/02 12:28:23 mav 1.39.16.1: #i84941# to handle the macro execution mode use MediaDescriptor only<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objshimp.hxx,v $
 *
 *  $Revision: 1.40 $
 *
 *  last change: $Author: rt $ $Date: 2008-01-29 15:29:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFX_OBJSHIMP_HXX
#define _SFX_OBJSHIMP_HXX

//#include <hash_map>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _DATETIME_HXX
#include <tools/datetime.hxx>
#endif

#include <svtools/securityoptions.hxx>
#include <sfx2/objsh.hxx>
#include "sfx2/docmacromode.hxx"
#include "bitset.hxx"

namespace svtools { class AsynchronLink; }

//====================================================================

DBG_NAMEEX(SfxObjectShell)

class SfxViewFrame;
struct MarkData_Impl
{
    String aMark;
    String aUserData;
    SfxViewFrame* pFrame;
};

class SfxFrame;
class SfxToolBoxConfig;
class SfxAcceleratorManager;
class SfxBasicManagerHolder;
struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess
{
    ::comphelper::EmbeddedObjectContainer* mpObjectContainer;
    SfxAcceleratorManager*  pAccMgr;
    SfxDocumentInfo*    pDocInfo;
    SfxConfigManager*   pCfgMgr;
    SfxBasicManagerHolder*
                        pBasicManager;
    SfxObjectShell&     rDocShell;
    ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
                        xBasicLibraries;
    ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
                        xDialogLibraries;
    ::sfx2::DocumentMacroMode
                        aMacroMode;
    SfxProgress*        pProgress;
    String              aTitle;
    String              aTempName;
    DateTime            nTime;
    sal_uInt16          nVisualDocumentNumber;
    sal_Int16           nDocumentSignatureState;
    sal_Int16           nScriptingSignatureState;
    sal_Bool            bTemplateConfig:1,
                        bInList:1,          // ob per First/Next erreichbar
                        bClosing:1,         // sal_True w"aehrend Close(), um Benachrichtigungs-Rekursionen zu verhindern
                        bSetInPlaceObj:1,   // sal_True, falls bereits versucht wurde pInPlaceObject zu casten
                        bIsSaving:1,
                        bPasswd:1,
                        bIsTmp:1,
                        bIsNamedVisible:1,
                        bIsTemplate:1,
                        bIsAbortingImport:1,  // Importvorgang soll abgebrochen werden.
                        bImportDone : 1, //Import schon fertig? Fuer AutoReload von Docs.
                        bInPrepareClose : 1,
                        bPreparedForClose : 1,
                        bWaitingForPicklist : 1,// Muss noch in die Pickliste
                        bModuleSearched : 1,
                        bIsBasicDefault : 1,
                        bIsHelpObjSh : 1,
                        bForbidCaching : 1,
                        bForbidReload : 1,
                        bSupportsEventMacros: 1,
                        bLoadingWindows: 1,
                        bBasicInitialized :1,
                        //bHidden :1, // indicates a hidden view shell
                        bIsPrintJobCancelable :1, // Stampit disable/enable cancel button for print jobs ... default = true = enable!
                        bOwnsStorage:1,
                        bNoBaseURL:1,
                        bInitialized:1,
                        bSignatureErrorIsShown:1,
                        bModelInitialized:1, // whether the related model is initialized
                        bPreserveVersions:1,
                        m_bMacroSignBroken:1, // whether the macro signature was explicitly broken
                        m_bNoBasicCapabilities:1,
                        bQueryLoadTemplate:1,
                        bLoadReadonly:1,
                        bUseUserData:1,
                        bSaveVersionOnClose:1;

    String              aNewName;  // Der Name, unter dem das Doc gespeichert
                                   // werden soll
    IndexBitSet         aBitSet;
    sal_uInt32               lErr;
    sal_uInt16              nEventId;           // falls vor Activate noch ein
                                            // Open/Create gesendet werden mu/s
    sal_Bool                bDoNotTouchDocInfo;

    AutoReloadTimer_Impl *pReloadTimer;
    MarkData_Impl*      pMarkData;
    sal_uInt16              nLoadedFlags;
    sal_uInt16              nFlagsInProgress;
    String              aMark;
    Size                aViewSize;          // wird leider vom Writer beim
    sal_Bool                bInFrame;           // HTML-Import gebraucht
    sal_Bool                bModalMode;
    sal_Bool                bRunningMacro;
    sal_Bool                bReloadAvailable;
    sal_uInt16              nAutoLoadLocks;
    SfxModule*              pModule;
    SfxFrame*               pFrame;
    SfxToolBoxConfig*       pTbxConfig;
    SfxEventConfigItem_Impl* pEventConfig;
    SfxObjectShellFlags     eFlags;
    svtools::AsynchronLink* pCloser;
    String                  aBaseURL;
    sal_Bool                bReadOnlyUI;
    SvRefBaseRef            xHeaderAttributes;
    sal_Bool                bHiddenLockedByAPI;
    sal_Bool                bInCloseEvent;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel;
    sal_uInt16              nStyleFilter;
    sal_Bool                bDisposing;

    sal_Bool                m_bEnableSetModified;
    sal_Bool                m_bIsModified;

    Rectangle               m_aVisArea;
    MapUnit                 m_nMapUnit;

    sal_Bool                m_bCreateTempStor;
    ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xDocStorage;

    sal_Bool                m_bIsInit;

    SfxObjectShell_Impl( SfxObjectShell& _rDocShell );
    virtual ~SfxObjectShell_Impl();

    // IMacroDocumentAccess overridables
    virtual sal_Int16 getImposedMacroExecMode() const;
    virtual sal_Bool setImposedMacroExecMode( sal_uInt16 nMacroMode );
    virtual ::rtl::OUString getDocumentLocation() const;
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getLastCommitDocumentStorage();
    virtual sal_Bool documentStorageHasMacros() const;
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const;
    virtual sal_Int16 getScriptingSignatureState() const;
    virtual void showBrokenSignatureWarning( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxInteraction ) const;
};

#endif

<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////
/*
 *  Template of a read routine
 */
/////////////////////////////////////////////////////////////////
#include <NrrdIO/NrrdIOAPI.h>

#include <hxfield/HxUniformScalarField3.h>
#include <Amira/HxMessage.h>
#include <teem/nrrd.h>

NRRDIO_API
int NrrdReader(const char* filename)
{

	Nrrd *nrrd = nrrdNew();
	if ( nrrdLoad( nrrd, filename, NULL ) )
		throw biffGetDone(NRRD);

    if ( nrrd->dim > 3 )
	{
		theMsg->printf("ERROR: for now, nrrd input can only handle data with dimension 3 or less.");
		return 0;
	}

    const int dims[3] =
	{
		(nrrd->dim > 0) ? nrrd->axis[0].size : 1,
		(nrrd->dim > 1) ? nrrd->axis[1].size : 1,
		(nrrd->dim > 2) ? nrrd->axis[2].size : 1
	};

	HxUniformScalarField3* field = NULL;

	switch ( nrrd->type )
	{
		case nrrdTypeUChar:  field = new HxUniformScalarField3(dims,MC_UINT8,nrrd->data); break;
		case nrrdTypeChar:   field = new HxUniformScalarField3(dims,MC_INT8,nrrd->data); break;
		case nrrdTypeUShort: field = new HxUniformScalarField3(dims,MC_UINT16,nrrd->data); break;
		case nrrdTypeShort:  field = new HxUniformScalarField3(dims,MC_INT16,nrrd->data); break;
		case nrrdTypeInt:    field = new HxUniformScalarField3(dims,MC_INT32,nrrd->data); break;
		case nrrdTypeFloat:  field = new HxUniformScalarField3(dims,MC_FLOAT,nrrd->data); break;
		case nrrdTypeDouble: field = new HxUniformScalarField3(dims,MC_DOUBLE,nrrd->data); break;
		default: break;
	}

	if(field == NULL)
	{
		theMsg->printf("ERROR: unknown nrrd input type.");
		return 0;
	}

	// Shouldn't need to check for data loading
	HxData::registerData(field, filename);

    return 1;
}

<commit_msg>Correctly loads voxel dimensions from nrrd data<commit_after>/////////////////////////////////////////////////////////////////
/*
 *  Template of a read routine
 */
/////////////////////////////////////////////////////////////////
#include <NrrdIO/NrrdIOAPI.h>

#include <hxfield/HxUniformScalarField3.h>
#include <Amira/HxMessage.h>
#include <teem/nrrd.h>

NRRDIO_API
int NrrdReader(const char* filename)
{

	Nrrd *nrrd = nrrdNew();
	if ( nrrdLoad( nrrd, filename, NULL ) )
		throw biffGetDone(NRRD);

    if ( nrrd->dim > 3 )
	{
		theMsg->printf("ERROR: for now, nrrd input can only handle data with dimension 3 or less.");
		return 0;
	}

    const int dims[3] =
	{
		(nrrd->dim > 0) ? nrrd->axis[0].size : 1,
		(nrrd->dim > 1) ? nrrd->axis[1].size : 1,
		(nrrd->dim > 2) ? nrrd->axis[2].size : 1
	};

	HxUniformScalarField3* field = NULL;

	switch ( nrrd->type )
	{
		case nrrdTypeUChar:  field = new HxUniformScalarField3(dims,MC_UINT8,nrrd->data); break;
		case nrrdTypeChar:   field = new HxUniformScalarField3(dims,MC_INT8,nrrd->data); break;
		case nrrdTypeUShort: field = new HxUniformScalarField3(dims,MC_UINT16,nrrd->data); break;
		case nrrdTypeShort:  field = new HxUniformScalarField3(dims,MC_INT16,nrrd->data); break;
		case nrrdTypeInt:    field = new HxUniformScalarField3(dims,MC_INT32,nrrd->data); break;
		case nrrdTypeFloat:  field = new HxUniformScalarField3(dims,MC_FLOAT,nrrd->data); break;
		case nrrdTypeDouble: field = new HxUniformScalarField3(dims,MC_DOUBLE,nrrd->data); break;
		default: break;
	}

	if(field == NULL)
	{
		theMsg->printf("ERROR: unknown nrrd input type.");
		return 0;
	}

	// First fetch axis spacing
	double spacing[3] = { 1.0, 1.0, 1.0 };
	for ( size_t ax = 0; ax < nrrd->dim; ++ax )
	{
		switch ( nrrdSpacingCalculate( nrrd, ax, spacing+ax, nrrd->axis[ax].spaceDirection ) )
		{
			case nrrdSpacingStatusScalarNoSpace:
				break;
			case nrrdSpacingStatusDirection:
				break;
			case nrrdSpacingStatusScalarWithSpace:
				theMsg->printf("WARNING: nrrdSpacingCalculate returned nrrdSpacingStatusScalarWithSpace\n");
				spacing[ax] = nrrd->axis[ax].spacing;
				break;
			case nrrdSpacingStatusNone:
			default:
				theMsg->printf("WARNING: no pixel spacings in Nrrd for axis %d ; setting to 1.0\n",ax);
				spacing[ax] = 1.0;
				break;
		}
	}

	// Now let's set the physical dimensions
	// This is done by defining the bounding box, the range of the voxel centres
	// given in the order: xmin,xmax,ymin ...
	float *bbox = field->bbox();
	bbox[0] = isnan(nrrd->spaceOrigin[0])?0.0f:(float) nrrd->spaceOrigin[0];
	bbox[2] = isnan(nrrd->spaceOrigin[1])?0.0f:(float) nrrd->spaceOrigin[1];
	bbox[4] = isnan(nrrd->spaceOrigin[2])?0.0f:(float) nrrd->spaceOrigin[2];

	// When a dimension is 1, Amira still seems to have a defined spacing
	bbox[1] = bbox[0] + (float) spacing[0] * ( dims[0] == 1 ? 1 : (dims[0] - 1) );
	bbox[3] = bbox[2] + (float) spacing[1] * ( dims[1] == 1 ? 1 : (dims[1] - 1) );
	bbox[5] = bbox[4] + (float) spacing[2] * ( dims[2] == 1 ? 1 : (dims[2] - 1) );

	// Shouldn't need to check for data loading
	HxData::registerData(field, filename);

    return 1;
}

<|endoftext|>