Create histogram from textfile with several binning boundaries

Dear all,

I want to create a histogram from a txt.file. The first 6 columns are the bin boundaries for the 3 parameter m, pt and y. The 7th column is the yield and the 8th one is the uncertainty. I have created a function to read the lines of this textfile.

void DecodeLine(std::string line, double &m_low, double &m_high, double &y_low, double &y_high, double pt_low, double pt_high, double yield, double uncert){
  TString rs(line.c_str());
  printf("rs: %s\n", rs.Data());
  TObjArray *toks = rs.Tokenize(" ");
  if(toks->GetEntries()!=9) return;
  m_low = ((TObjString *)toks->At(0))->String().Atof();
  m_high = ((TObjString *)toks->At(1))->String().Atof();
  y_low = ((TObjString *)toks->At(2))->String().Atof();
  y_high = ((TObjString *)toks->At(3))->String().Atof();
  pt_low = ((TObjString *)toks->At(4))->String().Atof();
  pt_high = ((TObjString *)toks->At(5))->String().Atof();
  yield = ((TObjString *)toks->At(6))->String().Atof();
  uncert = ((TObjString *)toks->At(7))->String().Atof();
   printf("m_low %f, m_low %f, y_low %f, y_high %f, pt_low %f, pt_high %f, yield %f, uncert %f", m_low, m_high, y_low, y_high, pt_low, pt_high, yield, uncert);
}

In my main function , I did this

ifstream in("results_DYPbPb_eppspdf_noresumbutkt_ptbins_mu1.txt");
  std::string  str;
  double m_low, m_high, pt_low,  pt_high, y_low, y_high, yield, uncert;
   
 while(getline(in,str)){
  if(str.find("#") < str.length()) continue;  // Line commented out
  if(str.length() == 0) continue;
  DecodeLine(str, m_low, m_high, pt_low,  pt_high, y_low, y_high, yield, uncert);
  if(y_low > 6) continue;

Im not sure how to create a histogram with these bin boundaries. At the end I want a TH2D histogram with m as X, pt as Y, the yield as dN/dm and the uncertainty.

I have attached the textfile.

Thanks

results_DYPbPb_eppspdf_noresumbutkt_ptbins_mu1.txt (607.7 KB)

Maybe @moneta can give you some tips

Hi,

You need to create an array (e.g. a std::vector) for the bin boundaries of the X (m) and Y (pt), and then use this constructor for TH2D:
https://root.cern.ch/doc/master/classTH2D.html#a075a0fbe5fa92d6ddac7cda6897e63a8
where xbins and ybins are the arrays with the bin boundaries

Then you need to call TH2::SetBinContent passing the bin numbers and yield values

If you need I could provide you an example

Lorenzo

1 Like

Hi thanks for the tips, yeah you can provide me an example to understand it better. What should I do with the parameters nbinsx and nbinsy?

Ok, I will provide you an example but I could do probably only next week.
nbinsx and nbinsy are the number of bins in the x and y axis. You should compute counting the boundaries when reading the file. Remember that the boundary array should have a dimension of nbins+1.

TH2::TH2

so my xbins is the array of my low-edges for each bin. Is this the first column or second column of my textfile? I am not sure.

You have two possibilities (which should return the same):

  1. you take all “…lo” (unique) values and the last one from the “…hi”,
  2. you take the first one from the “…lo” and then all “…hi” (unique) values.

BTW. You need to remove the last line from your “.txt” data file.

Hi thanks,

I did it, it worked finally!

One last question. I have the uncertainty in my txt file. Can I do something like that SetBinError(i, uncertainty) to have my uncertainty?

You can use SetBinContent and SetBinError.

Unfortunetly , I will get an eternal loop when I try to do a double loop over my nbinsx and nbinsy. What did I wrong?

Double_t m_low, m_high, y_low, y_high, pt_low, pt_high, yield, uncertainty;
    Int_t nbinsx = 25;
    Double_t binsmee[26] = {2, 2.25, 2.5, 2.75, 3., 3.25, 3.5, 3.75, 4., 4.25, 4.5, 4.75, 5., 5.25, 5.5, 5.75, 6, 6.25, 6.5, 6.75, 7., 7.25, 7.5, 7.75, 8., 20.};
    Int_t nbinsy = 41;
    Double_t binsptee[42] = {0., 0.25, 0.5, 0.75, 1., 1.25, 1.5, 1.75, 2., 2.25, 2.5, 2.75, 3., 3.25, 3.5, 3.75, 4., 4.25, 4.5, 4.75, 5., 5.25, 5.5, 5.75, 6., 6.25, 6.5, 6.75, 7., 7.25, 7.5, 7.75, 8., 8.25, 8.5, 8.75, 9., 9.25, 9.5, 9.75, 10., 20.};
    TH2D *drell = new TH2D("drell", "Drell Yann", nbinsx, binsmee, nbinsy, binsptee);
    ifstream in("results_DYPbPb_eppspdf_noresumbutkt_ptbins_mu1.txt");

    while (in) {
        in_pos = in.tellg();
        if (in >> m_low >> m_high >> y_low >> y_high >> pt_low >> pt_high >> yield >>
            uncertainty) {
		if(y_low > 6) continue;
	    yield = yield  * 1e-15 * 2.632e-11;
	    printf("Found entry, yield is %f\n", yield);
		for (int i=1;i<=nbinsx;i++)
		{
			for(int j=1;j<=nbinsy;j++)
				
			{	printf("Found entry, yield is %f\n", yield);
				drell->SetBinContent(i,j,yield);
				}
       
		}
        } else {
            in.clear();
            in.seekg(in_pos);
            
            if (getline(in, s)) {
                if (s.empty() || s.find("#") != std::string::npos) {
                } else {
                    cout << "Error in line: " << s << "\n";
                }
            }
        }
    }
	  

Do getline(in, s) as well after in_pos = in.tellg()?

You mean while(getline) after in_pos = in.tellg()?

My last suggestion is wrong. Please ignore it. I tried you macro. After commenting the printf, the macro quits normally. Maybe the printout slowed down the execution?