#include "Oscar97QA.h"



//___________
Oscar97QA::Oscar97QA(const char *inFileList,
		     const char *outFile) {
  mError = false;
  mDebug = false;
  //
  // Open list of root files
  //
  std::cout << "[Oscar97QA]: Trying to open file "
	    << inFileList << "...";
  mListFile = fopen(inFileList, "r");
  if (!mListFile) {
    std::cout << " [FAIL]" << std::endl;
    mError = true;
    return;
  }
  else {
    std::cout << " [OK]" << std::endl;
  }
  //
  // Create/recreate output file
  //
  std::cout << "[Oscar97QA]: Trying to create/recreate output file "
	    << outFile << "... ";
  mOut = new TFile(outFile, "RECREATE");
  if (!mOut) {
    std::cout << "[FAIL]" << std::endl;
    mError = true;
    return;
  }
  else {
    std::cout << "[OK]" << std::endl;
  }
  //
  // Create histograms
  //
  std::cout << "[Oscar97QA]: Creating histograms" << std::endl;
  // event
  hImpPar = new TH1D("hImpPar", ";impact (fm/c);#", 200, 0., 17.);
  // track
  hPx = new TH1D("hPx", ";p_{x} (GeV/c);#", 1000, -3., 3.);
  hPy = new TH1D("hPy", ";p_{y} (GeV/c);#", 1000, -3., 3.);
  hPz = new TH1D("hPz", ";p_{z} (GeV/c);#", 1000, -5., 5.);
  hPt = new TH1D("hPt", ";p_{t} (GeV/c);#", 500, 0., 3.);
  hXfr = new TH1D("hXfr", ";x_{fr} (fm/c);#", 1000, -50., 50.);
  hYfr = new TH1D("hYfr", ";y_{fr} (fm/c);#", 1000, -50., 50.);
  hZfr = new TH1D("hZfr", ";z_{fr} (fm/c);#", 1000, -50., 50.);
  hTfr = new TH1D("hTfr", ";t_{fr} (fm/c);#", 1000, 0., 200.);
  hEnergy = new TH1D("hEnergy", ";E (GeV);#", 1000, 0., 200.);
  hMSqrVsPt = new TH2D("hMSqrVsPt",
		       ";p_{t} (GeV/c);m^{2} (GeV^{2}/c^{4})",
		       500, 0., 3.,
		       1000, 0., 2.);
  hEta = new TH1D("hEta", ";#eta;#", 1000, -5, 5.);
}


//_____________
void Oscar97QA::MakeQA() {
  char buf[BFSZ] = {0};

  
  while (!feof(mListFile)) {
    // read next file from the list
    char *ret = fgets(buf, BFSZ, mListFile);
    if (!ret)   break;
    int len = strlen(buf);
    if (len != BFSZ)
      buf[len - 1] = '\0'; // last character may be '\n' (see man fgets)
    ReadFile(buf);
  }

  mOut->cd();
  
  hImpPar->Write();
  hPx->Write();
  hPy->Write();
  hPz->Write();
  hPt->Write();
  hXfr->Write();
  hYfr->Write();
  hZfr->Write();
  hTfr->Write();
  hEnergy->Write();
  hMSqrVsPt->Write();
  hEta->Write();
  
  mOut->Close();
}


//_____________
void Oscar97QA::ReadFile(const char *file) {
  //
  // Trying to open ROOT file
  //
  if (mDebug)
    std::cout << "[Oscar97QA]: Working with file "
	      << file << std::endl;
  TFile *fIn = new TFile(file, "READ");
  if (!fIn) {
    std::cout << "[Oscar97QA]: Can't open file "
	      << file << std::endl;
    return;
  }
  //
  // Associate tree
  //
  TTree *tree = (TTree *)fIn->Get("Oscar97Dst");
  Oscar97Event *event = new Oscar97Event;
  tree->SetBranchAddress("Oscar97Event", &event);
  unsigned long nEvents = tree->GetEntries();

  for (unsigned long iEvent = 0; iEvent < nEvents; iEvent++) {
    tree->GetEntry(iEvent);

    unsigned int nTracks = event->GetNTracks();
    hImpPar->Fill(event->GetImpactPar());
    TClonesArray *tracks = event->GetTracks();

    for (unsigned int iTrack = 0; iTrack < nTracks; iTrack++) {
      Oscar97Track *track = (Oscar97Track *)tracks->At(iTrack);
      float px = track->GetPx();
      float py = track->GetPy();
      float pz = track->GetPz();
      float pt = TMath::Sqrt(px*px + py*py);
      float p = TMath::Sqrt(px*px + py*py + pz*pz);
      float energy = track->GetEnergy();
      float mass = track->GetMass();
      float x = track->GetXfr();
      float y = track->GetYfr();
      float z = track->GetZfr();
      float t = track->GetTfr();
      float eta = 0.5*TMath::Log((p + pz)/(p - pz));
      
      hPx->Fill(px);
      hPy->Fill(py);
      hPz->Fill(pz);
      hXfr->Fill(x);
      hYfr->Fill(y);
      hZfr->Fill(z);
      hTfr->Fill(t);
      hPt->Fill(pt);
      hEnergy->Fill(energy);
      hMSqrVsPt->Fill(pt, mass*mass);
      hEta->Fill(eta);
    } // for (unsigned int iTrack = 0; iTrack < nTracks; iTrack++)
  } // for (unsigned long iEvent = 0; iEvent < nEvent; iEvent++)
}


//_____________
bool Oscar97QA::GetError() {
  return mError;
}


//_____________
void Oscar97QA::SetDebug(bool val) {
  mDebug = val;
}
