#define BUFSZ 0xFF


const float qMax   = 0.4;
const float qMin   = 0.;
const int   nBins  = 40;
const float qWidth = (qMax - qMin)/nBins;


void fillHist(TH1F *hQinv, TH1F *hNum, TH1F *hDen, FILE *file);
void fillHistOB(TH2F *hQinv3D, TH1F *hQinvOut, TH1F *hQinvBeam);



void crabOSL(const char *iOutwardsFN  = "q_outwards.dat",
	     const char *iSidewardsFN = "q_sidewards.dat",
	     const char *iBeamFN      = "q_beam.dat",
	     const char *oFileName = "CrabOSL.root") {
  FILE *fOutwards  = fopen(iOutwardsFN, "r");
  FILE *fSidewards = fopen(iSidewardsFN, "r");
  FILE *fBeam      = fopen(iBeamFN, "r");
  TFile *fOutFile = new TFile(oFileName, "RECREATE");
  //
  // One-dim CF
  //
  TH1F *hQinvOutwards = new TH1F("hQinvOutwards", "Outward direction;Q_{inv} (GeV/c);#",
				 nBins, qMin, qMax);
  TH1F *hQinvSidewards = new TH1F("hQinvSidewards", "Sideward direction;Q_{inv} (GeV/c);#",
				  nBins, qMin, qMax);
  TH1F *hQinvBeam = new TH1F("hQinvBeam", "Beam direction;Q_{inv} (GeV/c);#",
			     nBins, qMin, qMax);
  //
  // Numerators
  //
  TH1F *hNumOutwards = new TH1F("hNumOutwards", "Outward direction (numerator);Q_{inv} (GeV/c);#",
				nBins, qMin, qMax);
  TH1F *hNumSidewards = new TH1F("hNumSidewards", "Sideward direction (numerator);Q_{inv} (GeV/c);#",
				 nBins, qMin, qMax);
  TH1F *hNumBeam = new TH1F("hNumBeam", "Beam direction (numerator);Q_{inv} (GeV/c);#",
			    nBins, qMin, qMax);
  //
  // Denominators
  //
  TH1F *hDenOutwards = new TH1F("hDenOutwards", "Outward direction (denominator);Q_{inv} (GeV/c);#",
				nBins, qMin, qMax);
  TH1F *hDenSidewards = new TH1F("hDenSidewards", "Sideward direction (denominator);Q_{inv} (GeV/c);#",
				 nBins, qMin, qMax);
  TH1F *hDenBeam = new TH1F("hDenBeam", "Beam direction (denominator);Q_{inv} (GeV/c);#",
			    nBins, qMin, qMax);
  //
  // Projections
  //
  TH2F *hQinvOB = new TH2F("hQinvOL", ";Q^{Out}_{inv} (GeV/c);Q^{Long}_{inv} (GeV/c)",
			   nBins, qMin, qMax,
			   nBins, qMin, qMax);

  fillHist(hQinvOutwards, hNumOutwards, hDenOutwards, fOutwards);
  fillHist(hQinvSidewards, hNumSidewards, hDenSidewards, fSidewards);
  fillHist(hQinvBeam, hNumBeam, hDenBeam, fBeam);

  fclose(fOutwards);
  fclose(fSidewards);
  fclose(fBeam);

  hQinvOutwards->Write();
  hQinvSidewards->Write();
  hQinvBeam->Write();

  hNumOutwards->Write();
  hNumSidewards->Write();
  hNumBeam->Write();

  hDenOutwards->Write();
  hDenSidewards->Write();
  hDenBeam->Write();

  hQinvOB->Write();

  fOutFile->Close();
}


//_____________
void fillHist(TH1F *hQinv, TH1F *hNum, TH1F *hDen, FILE *file) {
  hQinv->Sumw2();
  char buf[BUFSZ] = {0};
  //
  // Skip 2 useless lines
  //
  fgets(buf, BUFSZ, file);
  fgets(buf, BUFSZ, file);
  
  float qInv, cf, dCf;
  int num, den;
  while(!feof(file)) {
    int ret = fscanf(file, "%f %f %f %i %i", &qInv, &cf, &dCf, &num, &den);

    if (ret == 5) { // check that 5 parameters were readed
      qInv /= 1e3; // MeV to GeV
      int bin = (int)(qInv/qWidth) + 1;
      hQinv->Fill(qInv, cf);
      hQinv->SetBinError(bin, dCf);
      hNum->Fill(qInv, num);
      hDen->Fill(qInv, den);
    }
    else
      fgets(buf, BUFSZ, file);
  }
}



void fillHistOB(TH2F *hQinvOL, TH1F *hQinvOut, TH1F *hQinvBeam) {
  float qOut, qBeam;
  float cfOut, cfBeam;


  for (unsigned int iBinOut = 1; iBinOut <= nBins; iBinOut++) {
    cfOut = hQinvOut->GetBinContent(iBinOut);
    qOut = qMin + qWidth*(iBinOut - 0.5);
    for (unsigned int iBinBeam = 1; iBinBeam <= nBins; iBinBeam++) {
      cfBeam = hQinvBeam->GetBinContent(iBinBeam);
      qBeam = qMin + qWidth*(iBinBeam - 0.5);
      
      hQinvOB->Fill(qOut, qBeam);
    } // for (unsigned int iBinBeam = 1; iBinBeam <= nBins; iBinBeam++)
  } // for (unsigned int iBinOut = 1; iBinOut <= nBins; iBinOut++)
}
