TH2 ProjectionY

Dear Rooters,

I am learning to use ProjectionY function in TH2 draw a 1D Projection to y axis from a 2D dot plot. What I am trying to do is like this:

I first draw a TCutG sub-region in 2D plot and then project 2D data to y axis. I know the (x,y) of each vertex in the TCutG sub-region. So I use GlobalBin = FindBin(x,y) to get corresponding Global Bin number. I try to use the smallest and the biggest GlobalBins to assign to arguments firstxbin and lastxbin in ProjectionY() function. It didn’t work. Then I try to use GetBinXYZ(globalxbin, firstxbin, biny, binz) to assign to firstxbin and lastxbin. It failed again.

So, my question is what value I should assign to firstxbin and lastxbin. Thank you very much for your help in advance! Appreciate for your advice :slight_smile:

The code is as below:

void TestDialog::Project2Y(){
	int CurReg = ActRegion;
	int Points = Region[CurReg]->GetN();
	char CurCutName[16], ProjName[16];
	//dX, dY represents the real double coordinates
	double dX=0.0, dY=0.0;
//	double dY_Bottom=0.0, dY_Top=0.0, dX_Left=0.0, dX_Right=0.0;
	//iX, iY represents the relative int coordinates in XVertex and YVertex
	int fxbin=0, lxbin=-1; //First xbin, Last xbin
	int iX=0, iY=0;
	int iY_Bottom=YVertex[CurReg][0], iY_Top=YVertex[CurReg][0], iX_Left=XVertex[CurReg][0], iX_Right=XVertex[CurReg][0];

	for(int i=0;i<Points;i++){
		ParseXY(XVertex[CurReg][i], YVertex[CurReg][i], dX, dY); 
		iX = fHpxpy->FindBin(dX, dY);
		if(i==0){			
			fxbin = iX;
			lxbin = fxbin;
		} else {
			if(fxbin > iX)
				fxbin = iX;
			if(lxbin < iX)
				lxbin = iX;
		}
	}

	sprintf(CurCutName,"[CUT%d]",CurReg+1);
	sprintf(ProjName, "Projection%d",CurReg+1);
	if(fHprojy)
		fHprojy->Delete();	
//	fHpxpy->GetBinXYZ(fxbin, fxbin, iX, iY);
//	fHpxpy->GetBinXYZ(lxbin, lxbin, iX, iY);
	fxbin = 10;
	lxbin = 35;
	printf("1stxbin = %d, lastxbin = %d\n", fxbin, lxbin);
	fHprojy = (TH1F*)fHpxpy->ProjectionY(ProjName, fxbin, lxbin, "[CUT1]");
	fCanvas[2]->cd();
	fHprojy->SetTitle(ProjName);
	fHprojy->SetFillColor(kBlue);
	fHprojy->SetTickLength(0.02);
	fHprojy->GetXaxis()->SetTicks("+-");
	fHprojy->Draw("LF2");
	fCanvas[2]->Modified();
	fCanvas[2]->Update();

}


if you have a TH2 with NX bins and want to project along Y using a TCutg, you can do something like

TH1D *py = h2->ProjectionY("py",1,NX,"[mycut]"); You have to specify different values for firstbin, lastbin only if you want to select a subrange in X of your TCutG

Rene

Dear Mr. Brun,

Thank you very much for your suggestion. I use GetNbinsX() to get NX.

NX = h2->GetNbinsX()

The output is shown in the attachment. The TCutG ([color=#FF0000]red[/color]) in the first canvas shows that the selected y projection region is from -2.4 to 1.6. However, in the second canvas, projection to y axis shows that the selected region is from -3 to 3, almost including all the data in h2. When I change the region of TCutG, the projection doesn’t change.

Could you please give me some advice on how to solve this problem?

Thank you very much again for your help!

Kind regards


Could you provide the shortest possible running script reproducing this problem?

Rene

Hi Rene,

I attached the sample code. The code which is related to drawing TCutG sub-range and projection to y axis is behind the comments [color=#80FF40]/Build Polygon Selecting Region/[/color].

Now by assigning firstxbin = ybin of the top vertex of the TCutG region and lastxbin = ybin of the bottom vertex of the TCutG region, I can project correct y axis range to the 1d histogram. But when I drag the sub-range along x axis, the projected histogram doesn’'t change, which are shown in the attachment. It seems that ProjectionY() function projects the whole area specified by firstxbin and lastxbin to y axis, no matter how the TCutG sub-range changes.

Thank you so much for your help!

Best regards.





projections_a.C (24.1 KB)

Hello fellow root users,

I am having the same issue with the TCutG apparently not being applied to the ProjectionX() call. I am using root 5.34/05 and 5.26/00 . Here is the code I am using:

hM2vM1 = (TH2*) gDirectory->Get("m2_vs_m1"); // A TH2D object 

   TCutG *cutM2vM1 = new TCutG("cutM2vM1",11);
   cutM2vM1->SetVarX("M1 (amu)");
   cutM2vM1->SetVarY("M2 (amu)");
   cutM2vM1->SetFillColor(1);
   cutM2vM1->SetPoint(0,78.7533,162.114);
   cutM2vM1->SetPoint(1,89.9967,134.028);
   cutM2vM1->SetPoint(2,105.483,121.704);
   cutM2vM1->SetPoint(3,122.666,103.362);
   cutM2vM1->SetPoint(4,138.577,87.5992);
   cutM2vM1->SetPoint(5,170.186,79.0013);
   cutM2vM1->SetPoint(6,172.307,86.4528);
   cutM2vM1->SetPoint(7,124.364,112.533);
   cutM2vM1->SetPoint(8,108.241,128.009);
   cutM2vM1->SetPoint(9,84.0568,167.56);
   cutM2vM1->SetPoint(10,78.7533,162.114);

//cutM2vM1->SetLineColor(kRed);
//cutM2vM1->Draw("AL");
//hM2vM1->Draw("same");

TCanvas* cM1_cut = new TCanvas();

TH1D* hM1_cut;
TH1D* hM1;

hM1 = hM2vM1->ProjectionX("hM1",hM2vM1->GetXaxis()->FindBin(60),hM2vM1->GetXaxis()->FindBin(180));

hM1_cut = hM2vM1->ProjectionX("hM1_cut",hM2vM1->GetXaxis()->FindBin(60),hM2vM1->GetXaxis()->FindBin(180),"[cutM2vM1]");
hM1_cut->SetLineColor(kRed);
hM1_cut->Draw();

hM1->Draw("same");

No matter how I run/edit the cut, I get no change between hM1 and hM1_cut .

Any thoughts?

Thanks so much!
Dan

Your macro access a TH2 we do not have.

hM2vM1 = (TH2*) gDirectory->Get("m2_vs_m1"); // A TH2D object 

can you provide a standalone running example ?

I have attached a macro to get the histogram loaded. When I load this file and then execute the following:

   TCutG *cutM2vM1 = new TCutG("cutM2vM1",11);
   cutM2vM1->SetVarX("M1 (amu)");
   cutM2vM1->SetVarY("M2 (amu)");
   cutM2vM1->SetFillColor(1);
   cutM2vM1->SetPoint(0,78.7533,162.114);
   cutM2vM1->SetPoint(1,89.9967,134.028);
   cutM2vM1->SetPoint(2,105.483,121.704);
   cutM2vM1->SetPoint(3,122.666,103.362);
   cutM2vM1->SetPoint(4,138.577,87.5992);
   cutM2vM1->SetPoint(5,170.186,79.0013);
   cutM2vM1->SetPoint(6,172.307,86.4528);
   cutM2vM1->SetPoint(7,124.364,112.533);
   cutM2vM1->SetPoint(8,108.241,128.009);
   cutM2vM1->SetPoint(9,84.0568,167.56);
   cutM2vM1->SetPoint(10,78.7533,162.114);

cutM2vM1->SetLineColor(kRed);
cutM2vM1->Draw("AL");
m2_vs_m1->Draw("same");

TCanvas* cM1_cut = new TCanvas();

TH1D* hM1_cut;
TH1D* hM1;

hM1 = m2_vs_m1->ProjectionX("hM1",m2_vs_m1->GetXaxis()->FindBin(60),m2_vs_m1->GetXaxis()->FindBin(180));

hM1_cut = m2_vs_m1->ProjectionX("hM1_cut",m2_vs_m1->GetXaxis()->FindBin(60),m2_vs_m1->GetXaxis()->FindBin(180),"[cutM2vM1]");
hM1_cut->SetLineColor(kRed);
hM1_cut->Draw();

hM1->Draw("same");

I get the previously noted behaviour.
m2_vs_m1.C (1.65 MB)

Attached find a working version of your macro.
The workaround was to have your cut name in lower case.
Right now the option string is entirely converted to lower case in ProjectionX.
That’s why your cut with Upper Case letters was ignored.
We will fix that.
m2_vs_m1.C (1.65 MB)

A JIRA item (ROOT-7097) is open for this bug

sft.its.cern.ch/jira/browse/ROOT-7097

Lorenzo