#include "StHbtMaker/CorrFctn/gregsBPLCMSFrame3DCorrFctnKt.h"
#include <cstdio>
#include <sstream>

#ifdef __ROOT__
ClassImp(gregsBPLCMSFrame3DCorrFctnKt)
#endif

//_________________
gregsBPLCMSFrame3DCorrFctnKt::gregsBPLCMSFrame3DCorrFctnKt(char *title,
							   const int &nbins,
							   const float &QLo, 
							   const float &QHi,
							   const int& nCFs, 
							   const float& KtLo, 
							   const float& KtHi) {

  // set some stuff...

  mNumberCFs = nCFs;
  mKtMin = KtLo;
  mKtMax = KtHi;
  mDeltaKt = (mKtMax-mKtMin)/mNumberCFs;

  stringstream TitNum,TitDen,TitQinv,TitCurrent;
  TitNum.str("");TitDen.str("");TitQinv.str("");TitCurrent.str("");
  TitNum<<title<<"_Num";
  TitDen<<title<<"_Den";
  TitQinv<<title<<"_Qinv";

  // set up numerator
  mNumerator = new StHbt3FHisto[mNumberCFs];
  // set up denominator
  mDenominator = new StHbt3FHisto[mNumberCFs];
  // set up ave qInv
  mQinvHisto = new StHbt3FHisto[mNumberCFs];
 
  //Histogram loop
  for(int i=0; i<mNumberCFs; i++) {
    
    TitCurrent.str("");
    TitCurrent << TitNum.str() << "_bin_" << i;
    mNumerator[i].SetName(TitCurrent.str().c_str());
    mNumerator[i].SetTitle(TitCurrent.str().c_str());
    mNumerator[i].SetBins(nbins,QLo,QHi,nbins,QLo,QHi,nbins,QLo,QHi);
    mNumerator[i].SetDirectory(0);
    mNumerator[i].Sumw2();

    TitCurrent.str("");
    TitCurrent << TitDen.str() << "_bin_" << i;
    mDenominator[i].SetName(TitCurrent.str().c_str());
    mDenominator[i].SetTitle(TitCurrent.str().c_str());
    mDenominator[i].SetBins(nbins,QLo,QHi,nbins,QLo,QHi,nbins,QLo,QHi);
    mDenominator[i].SetDirectory(0);
    mDenominator[i].Sumw2();

    TitCurrent.str("");
    TitCurrent << TitQinv.str() << "_bin_" << i;
    mQinvHisto[i].SetName(TitCurrent.str().c_str());
    mQinvHisto[i].SetTitle(TitCurrent.str().c_str());
    mQinvHisto[i].SetBins(nbins,QLo,QHi,nbins,QLo,QHi,nbins,QLo,QHi);
    mQinvHisto[i].SetDirectory(0);
    mQinvHisto[i].Sumw2();
  }
}

//_________________
gregsBPLCMSFrame3DCorrFctnKt::~gregsBPLCMSFrame3DCorrFctnKt() {

  delete [] mNumerator;
  delete [] mDenominator;
  delete [] mQinvHisto;
}

//_________________
void gregsBPLCMSFrame3DCorrFctnKt::WriteOutHistos() {

  for(int i=0; i<mNumberCFs; i++) {
    mNumerator[i].Write();
    mDenominator[i].Write();
    mQinvHisto[i].Write();
  }
}

//_________________
void gregsBPLCMSFrame3DCorrFctnKt::Finish() {
  
  //Just making the qInv weight correction
  /*
  for(int i=0; i<mNumberCFs; i++) {
    mQinvHisto[i].Divide(&mDenominator[i]);
  }
  */
}

//_________________
void gregsBPLCMSFrame3DCorrFctnKt::AddRealPair(const StHbtPair* pair){

  if (mPairCut){
    if (!(mPairCut->Pass(pair))) return;
  }

  int mIndex = (int)(((fabs(pair->kT())-mKtMin)/mDeltaKt));
  if ((mIndex>=0)&&(mIndex<mNumberCFs)) {
    double qOut = fabs(pair->qOutCMS());
    double qSide = fabs(pair->qSideCMS());
    double qLong = fabs(pair->qLongCMS());

    mNumerator[mIndex].Fill(qOut,qSide,qLong);
  }
}

//_________________
void gregsBPLCMSFrame3DCorrFctnKt::AddMixedPair(const StHbtPair* pair){

  if (mPairCut){
    if (!(mPairCut->Pass(pair))) return;
  }

  int mIndex = (int)(((fabs(pair->kT())-mKtMin)/mDeltaKt));
  if ((mIndex>=0)&&(mIndex<mNumberCFs)) {
    double Qinv = fabs(pair->qInv()); 
    double qOut = fabs(pair->qOutCMS());
    double qSide = fabs(pair->qSideCMS());
    double qLong = fabs(pair->qLongCMS());


    mDenominator[mIndex].Fill(qOut,qSide,qLong,1.0);
    mQinvHisto[mIndex].Fill(qOut,qSide,qLong,Qinv);
  }
}

//_________________
StHbtString gregsBPLCMSFrame3DCorrFctnKt::Report() {

  int mNumeratorEntries=0;
  int mDenominatorEntries=0;
  int mQinvHistoEntries=0;

  for (int i=0; i<mNumberCFs; i++){
    mNumeratorEntries += (int)mNumerator[i].GetEntries();
    mDenominatorEntries += (int)mDenominator[i].GetEntries();
    mQinvHistoEntries += (int)mQinvHisto[i].GetEntries();
  }

  string stemp = "gregs LCMS Frame Bertsch-Pratt 3D Correlation Function Report:\n";
  char ctemp[100];
  sprintf(ctemp,"Number of entries in numerator:\t%E\n",mNumerator->GetEntries());
  stemp += ctemp;
  sprintf(ctemp,"Number of entries in denominator:\t%E\n",mDenominator->GetEntries());
  stemp += ctemp;
  sprintf(ctemp,"Number of entries in Qinv histo:\t%E\n",mQinvHisto->GetEntries());
  stemp += ctemp;

  StHbtString returnThis = stemp;
  return returnThis;
}
