#define BUFSZ 0xFF


void crab3D(const char *iFileName = "qinv3d.dat",
	    const char *oFileName = "Crab3D.root") {
  const float qMax   = 0.4;
  const float qMin   = 0.;
  const int   nBins  = 40;
  const float qWidth = (qMax - qMin)/nBins;
  FILE *iFile = fopen(iFileName, "r");
  char buf[BUFSZ] = {0};
  TFile *oFile = new TFile(oFileName, "RECREATE");
  TH3F *hQinvCF = new TH3F("hQinvCF", ";Q^{x}_{inv} (GeV/c);Q^{y}_{inv} (GeV/c);Q^{z}_{inv} (GeV/c)",
			   nBins, qMin, qMax,
			   nBins, qMin, qMax,
			   nBins, qMin, qMax);
  TH3F *hQinv = new TH3F("hQinv", ";Q^{x}_{inv} (GeV/c);Q^{y}_{inv} (GeV/c);Q^{z}_{inv} (GeV/c)",
			 nBins, qMin, qMax,
			 nBins, qMin, qMax,
			 nBins, qMin, qMax);
  TH3F *hQinvNum = new TH3F("hQinvNum", "Numerator;Q^{x}_{inv} (GeV/c);Q^{y}_{inv} (GeV/c);Q^{z}_{inv} (GeV/c)",
			    nBins, qMin, qMax,
			    nBins, qMin, qMax,
			    nBins, qMin, qMax);
  TH3F *hQinvDen = new TH3F("hQinvDen", "Denominator;Q^{x}_{inv} (GeV/c);Q^{y}_{inv} (GeV/c);Q^{z}_{inv} (GeV/c)",
			    nBins, qMin, qMax,
			    nBins, qMin, qMax,
			    nBins, qMin, qMax);
  TProfile2D *profXY, *profZY, *profZX;
  
  
  //
  // Skip 2 useless lines
  //
  fgets(buf, BUFSZ, iFile);
  fgets(buf, BUFSZ, iFile);
  
  float qInvX, qInvY, qInvZ, cf, dCf, num, den, norm;
  int numCounts, denCounts;
  while(!feof(iFile)) {
    int ret = fscanf(iFile, "%f %f %f %f %f %i %i %f %f %f", &qInvX, &qInvY, &qInvZ, &cf, &dCf, &numCounts, &denCounts, &norm, &num, &den);
    qInvX /= 1e3; //
    qInvY /= 1e3; // from MeV to GeV
    qInvZ /= 1e3; //
    if (ret != 10) { // 10 - number of parameters to read
      fgets(buf, BUFSZ, iFile);
      continue;
    }
    hQinvCF->Fill(qInvX, qInvY, qInvZ, cf);
    hQinv->Fill(qInvX, qInvY, qInvZ);
    int binX = (int)(qInvX/qWidth) + 1;
    int binY = (int)(qInvY/qWidth) + 1;
    int binZ = (int)(qInvZ/qWidth) + 1;

    hQinvCF->SetBinError(binX, binY, binZ, dCf);
    hQinv->SetBinError(binX, binY, binZ, 1.);
    
    hQinvNum->SetBinContent(binX, binY, binZ, num*norm);
    hQinvDen->SetBinContent(binX, binY, binZ, den);
    hQinvNum->SetBinError(binX, binY, binZ, sqrt(num)*norm);
    hQinvDen->SetBinError(binX, binY, binZ, sqrt(den));
  }
  hQinvNum->Sumw2();
  hQinvDen->Sumw2();

  profXY = hQinv->Project3DProfile("xy");
  profXY->GetXaxis()->SetTitle("Q^{x}_{inv} (GeV/c)");
  profXY->GetYaxis()->SetTitle("Q^{y}_{inv} (GeV/c)");
  profXY->Write();
    
  profZY = hQinv->Project3DProfile("ZY");
  profZY->GetXaxis()->SetTitle("Q^{z}_{inv} (GeV/c)");
  profZY->GetYaxis()->SetTitle("Q^{y}_{inv} (GeV/c)");
  profZY->Write();

  profZX = hQinv->Project3DProfile("ZX");
  profZX->GetXaxis()->SetTitle("Q^{z}_{inv} (GeV/c)");
  profZX->GetYaxis()->SetTitle("Q^{x}_{inv} (GeV/c)");
  profZX->Write();
  
  hQinv->Write();
  hQinvCF->Write();
  hQinvNum->Write();
  hQinvDen->Write();
  
  fclose(iFile);
  oFile->Close();
}
