Subset of 2D histogram

Dear root experts,

I am trying to get a subset of 2D histogram from a bigger one.
The original histogram is the following:
Screen Shot 2024-01-22 at 1.34.50 PM
The histogram is defined as following:

TH2D*  tempHist2D = new TH2D(" tempHist2D","" , 30,30,120,30,10,40);

Now I would like to have sub-set of this 2D histogram as following:

 TH2D* tempHist2DBis = new TH2D("tempHist2DBis","" , 2,105,111,2,30,32);

Here the code I wrote for that:

TH2D *tempHist2D;
//TH2D* tempHist2DBis = new TH2D("tempHist2DBis","" , 30,30,120,30,10,40);
 TH2D* tempHist2DBis = new TH2D("tempHist2DBis","" , 2,105,111,2,30,32);
 TFile *myfile = new TFile("inputFiles/BRscaled_gaussiansignal_4echannel_mZd31_mH108GeV.root");
 tempHist2D  =(TH2D*)myfile->Get("Nominal/sig");
   int Nbinx = tempHist2D->GetNbinsX();
  int Nbiny = tempHist2D->GetNbinsY();
  int binxy,x,y,z;
  for (int i =0; i < Nbinx; i++)
		{
		  for (int j =0; j< Nbiny; j++)
		    {
		      binxy = tempHist2D->GetBin(i,j);
		      tempHist2D->GetBinXYZ(binxy,x, y,z);
		      if ( tempHist2D->GetXaxis()->GetBinCenter(i) >= 105 && tempHist2D->GetXaxis()->GetBinCenter(i) <= 111)
			{
			  if (tempHist2D->GetYaxis()->GetBinCenter(j) >= 30 && tempHist2D->GetYaxis()->GetBinCenter(j) <= 32) {
			    tempHist2DBis->SetBinContent(i,j,tempHist2D->GetBinContent(i,j));
			  }
			}
		      
		    }
		}
  
  tempHist2DBis->Draw("colz");

It gives me this:
Screen Shot 2024-01-22 at 1.48.39 PM
Which is not what I want because the range is the same as the original one.
I was trying to change the tempHist2DBis definition by this:

TH2D* tempHist2DBis = new TH2D("tempHist2DBis","" , 2,105,111,2,30,32);

But this results to an empty histogram.

Do you have any idea?

SetRangeUser doesn’t seem to help, since this seem to change only the visualization.
I attached the root file.
BRscaled_gaussiansignal_4echannel_mZd31_mH108GeV.root (12.0 KB)

Best,

Diallo.

Hi @diboye,

there is quite some confusion with the indices there :slight_smile:

I think the easiest would be to:

  • Figure out the bin coordinates for each bin in your new subset histogram
  • Look up the bin content for that coordinates in the full hist
  • Set the bin content (and maybe errors too) of the subset histogram accordingly
TFile* file = TFile::Open(
    "BRscaled_gaussiansignal_4echannel_mZd31_mH108GeV.root");

TH2F* tempHist2D = file->Get<TH2F>("Nominal/sig");
TH2D* tempHist2DBis =
    new TH2D("tempHist2DBis", "", 2, 105, 111, 2, 30, 32);

// Starting with 1 because bin zero is the underflow bin
for (int i = 1; i <= tempHist2DBis->GetNbinsX(); i++) {
  for (int j = 1; j <= tempHist2DBis->GetNbinsY(); j++) {
    double x = tempHist2DBis->GetXaxis()->GetBinCenter(i);
    double y = tempHist2DBis->GetYaxis()->GetBinCenter(j);
    double content =
        tempHist2D->GetBinContent(tempHist2D->FindBin(x, y));
    tempHist2DBis->SetBinContent(i, j, 0, content);
  }
}

tempHist2DBis->Draw("colz text");

I hope that helps!

Cheers,
Jonas

PS: Not I added text to the bins in the drawing, which is quite useful for checks.

Thanks a lot Jonas, that works pretty well.

Best,

Diallo.

Hi!! of course the way @jonas has done it the best way to go. Looking at your code the reason it wasn’t giving the desires output is because your subset histogram has 2 bins in X and 2 bins in Y but you were trying to fill up 26, 27th bin in X and 21,22 bin in Y. I slightly modified your code and it works perfectly fine.

  for (int i = 1; i < Nbinx; i++)
	{
	  for (int j = 1; j < Nbiny; j++)
    {
      
      if ( tempHist2D->GetXaxis()->GetBinCenter(i) >= 105 && tempHist2D->GetXaxis()->GetBinCenter(i) <= 111)
	    {
	      if (tempHist2D->GetYaxis()->GetBinCenter(j) >= 30 && tempHist2D->GetYaxis()->GetBinCenter(j) <= 32)
	      {
	      	// cout << "for i = " << i << " and j = " << j << "bin content is " << tempHist2D->GetBinContent(i,j) << endl;
	      	tempHist2DBis->SetBinContent(i-25, j-20, tempHist2D->GetBinContent(i,j));
	      }
	    }
      
    }
	}

Hope the code itself makes sense.

Cheers
Shiva

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.