#include "StHbtMaker/Cut/nikTrackCut.h"
#include <sstream>

#ifdef __ROOT__
ClassImp(nikTrackCut)
#endif


//_________________
nikTrackCut::nikTrackCut() {

  mNTracksPassed = 0;
  mNTracksFailed = 0;

  mEta[0]  = -1e9;   mEta[1] = +1e9; 
  mP[0]    = -1e9;   mP[1]   = +1e9;
  mPt[0]   = -1e9;   mPt[1]  = +1e9;
  mPx[0]   = -1e9;   mPx[1]  = +1e9;
  mPy[0]   = -1e9;   mPy[1]  = +1e9;
  mPz[0]   = -1e9;   mPz[1]  = +1e9;
  mCharge  = 0;
}


//_________________
nikTrackCut *nikTrackCut::Clone() {
  nikTrackCut *c = new nikTrackCut(*this); return c;
}


//_________________
nikTrackCut::nikTrackCut(const nikTrackCut &c) : StHbtTrackCut(c) {

  mNTracksPassed = 0;
  mNTracksFailed = 0;

  mCharge  = c.mCharge;
  mP[0]    = c.mP[0];     mP[1]   = c.mP[1];
  mPt[0]   = c.mPt[0];    mPt[1]  = c.mPt[1];
  mPx[0]   = c.mPx[0];    mPx[1]  = c.mPx[1];
  mPy[0]   = c.mPy[0];    mPy[1]  = c.mPy[1];
  mPz[0]   = c.mPz[0];    mPz[1]  = c.mPz[1];
  mEta[0]  = c.mEta[0];   mEta[1] = c.mEta[1];
}


//_________________
nikTrackCut::~nikTrackCut() {
  /* empty */
}


//_________________
bool nikTrackCut::Pass(const StHbtTrack *track) {

  //mMass has to be set in the macros and defined in the base class
  float p       = track->P().mag();
  float pt      = track->P().perp();
  float px      = track->P().x();
  float py      = track->P().y();
  float pz      = track->P().z();
  float eta     = 0.5*::log( (p + pz)/(p - pz) );
  float massSqr = track->TofMassSqr();
  //Main patterns
  bool mGoodCharge = mCharge == track->Charge();
  bool mGoodTrack = ((p >= mP[0] && p <= mP[1]) &&
		     (pt >= mPt[0] && pt <= mPt[1]) &&
		     (px >= mPx[0] && px <= mPx[1]) &&
		     (py >= mPy[0] && py <= mPy[1]) &&
		     (pz >= mPz[0] && pz <= mPz[1]) &&
		     (eta >= mEta[0] && eta <= mEta[1]) &&
		     (massSqr >= mMassSqr[0] &&
		      massSqr <= mMassSqr[1]));

  bool mPassTrack = mGoodCharge && mGoodTrack;
  
  mPassTrack ? mNTracksPassed++ : mNTracksFailed++;
}


//_________________
StHbtString nikTrackCut::Report() {

  stringstream rep_str;
  rep_str << std::endl << "--== nikTrackCut ==--" << std::endl
	  << "Charge: " << mCharge << std::endl
	  << mP[0] << " <= p <= " << mP[1] << std::endl
	  << mPt[0] << " <= pT <= " << mPt[1] << std::endl
    	  << mPx[0] << " <= pX <= " << mPx[1] << std::endl
    	  << mPy[0] << " <= pY <= " << mPy[1] << std::endl
    	  << mPz[0] << " <= pZ <= " << mPz[1] << std::endl
	  << mMassSqr[0] << " <= massSqr <= " << mMassSqr[1] << std::endl
	  << mEta[0] << " <= PseudoRapidity <= " << mEta[1] << std::endl
	  << " >>> N Tracks passed: " << mNTracksPassed << std::endl
	  << " >>> N Tracks failed: " << mNTracksFailed << std::endl;

  return rep_str.str();
}


//_________________
void nikTrackCut::SetP(float lo, float hi) {
  mP[0] = lo;   mP[1] = hi;
}


//_________________
void nikTrackCut::SetPt(float lo, float hi) {
  mPt[0] = lo;   mPt[1] = hi;
}


//_________________
void nikTrackCut::SetPx(float lo, float hi) {
  mPx[0] = lo;   mPx[1] = hi;
}


//_________________
void nikTrackCut::SetPy(float lo, float hi) {
  mPy[0] = lo;   mPy[1] = hi;
}


//_________________
void nikTrackCut::SetPz(float lo, float hi) {
  mPz[0] = lo;   mPz[1] = hi;
}


//_________________
void nikTrackCut::SetEta(float lo, float hi) {
  mEta[0] = lo;   mEta[1] = hi;
}


//_________________
void nikTrackCut::SetMassSqr(float lo, float hi) {
  mMassSqr[0] = lo;   mMassSqr[1] = hi;
}


//_________________
void nikTrackCut::SetCharge(int charge) {
  mCharge = charge;
}
