Dear Rooter

I produce some plots with Ttree with bin fixed ,I want to create a variable bin Ttree with a binning such

that the entries per bin is about the same.

Thanks for your kind help.

Sandra

Dear Rooter

I produce some plots with Ttree with bin fixed ,I want to create a variable bin Ttree with a binning such

that the entries per bin is about the same.

Thanks for your kind help.

Sandra

A TTree itself has no bins. The histograms you produce using a given TTree has bins. When you use a command like.

```
tree->Draw("x");
```

An histograming operation will be done on the `x`

variable in the TTree `tree`

. By default the histogram created (`htemp`

) has equidistant bins. If you want non-equisitant bins you should create a such histogram (`h_neq`

) before performing the `Draw`

and then do it as follow:

```
tree->Draw("x>>h_neq");
```

thank you for your reply.

Exactly the TTree has no bin but when I want to read my TTree I create Histograms with bin fix.

you can find bellow what I did :

```
TTree *t4 = (TTree*)f->Get("t4");
Double_t ,TST_Ntest,TST_Vtest;
t4->SetBranchAddress("TST_Ntest",&TST_Ntest);
TH1D *TST_N = new TH1D("TST","",10, 0.0, 100.);
/////////////Create bin fix///////////////
Int_t nentries = 41967;
TST_N->FillRandom("gaus",nentries);
Double_t xbins[41968];
Int_t k=0;
TAxis *axis = TST_N->GetXaxis();
for (Int_t i=1;i<=50;i++) {
Int_t y = (Int_t)TST_N->GetBinContent(i);
if (y <=0) continue;
Double_t dx = axis->GetBinWidth(i)/y;
Double_t xmin = axis->GetBinLowEdge(i);
for (Int_t j=0;j<y;j++) {
xbins[k] = xmin +j*dx;
k++;
}
}
xbins[k] = axis->GetXmax();
TH1F *hnew = new TH1F("hnew","rebinned",k,xbins);
hnew->FillRandom("gaus",10*nentries);
//rebin hnew keeping only 50% of the bins
Double_t xbins2[33575];
Int_t kk=0;
for (Int_t j=0;j<k;j+=2) {
xbins2[kk] = xbins[j];
kk++;
}
xbins2[kk] = xbins[k];
TH1F *hnew2 = (TH1F*)hnew->Rebin(kk,"hnew2",xbins2);
//draw the 3 histograms
TCanvas *c1 = new TCanvas("c1","c1",800,1000);
c1->Divide(1,3);
c1->cd(1);
TST_N->Draw();
c1->cd(2);
hnew->Draw();
c1->cd(3);
hnew2->Draw();
```

But I have got strang plot and the number of entry are increased .

Cheers,

Sandra

As far as can see, in your example `TST_N`

and `h new`

are filled with random numbers, `h_new2`

is empty and you do not use the TTree `t4`

You are right. Could you please tell me what I can to do with this essue because I change TST_N with TST_Ntest but I got this error :

non class,struct,union object TST_Vtest used with . or -> macro.c:17:

*** Interpreter error recovered ***

What is the name of the variable you want to see in the `TTree`

named `t4`

?

The name of the variable that I want to see is “TST_Ntest” and I use : t4->SetBranchAddress(“TST_Ntest”,&TST_Ntest); to read

Just do:

```
TTree *t4 = (TTree*)f->Get("t4");
t4->Draw("TST_Ntest");
```

```
t4->Draw("TST_Ntest");
```

this to draw TST_Ntest variable with bin fixed but for me I want variable bin with the same entry .

Example :

This is an Let’s assume we have a TST histogram from 0. to 100 GeV. with 1000 entrie. Let’s assume you have created this histograms with 50 bins

we want to have 5 bins… meaning each bin will have 200 entries. SO now we should find the intervals [TST_min,TST_max] corresponding to bin contents ofabout 200 entries each…

Then you define a (double or single) 5+1 vector like this:

```
Double_t TST_edges[6] = {TST_min_1 , TST_max_1, TST_max_2, TST_max_3, TST_max_4, TST_max_5}
```

So you an now create a new histograms as follow:

```
TH1* h_new = new TH1D("name", "title", 5, TST_edges);
```

with 5 bins corresponding to TST_edges with each bin having about 200 entries…

But for me I have 41967 entry and Idon’t know what is criteria to transform the histogram bins from constant bin to variable bin.

Ok. So now you should create the variable bin size histogram using this constructor.

Let say you call this histogram `h1_neq`

.

Then you do:

```
t4->Draw("TST_Ntest >> h1_neq");
```

I imagine you could determine the bin edges as such:

```
#include <algorithm>
#include <vector>
//Set the number of bins
const int numBins = 10;
//Determine the number of counts per bin
int countsPerBin = tree->GetEntries() / numBins;
//Loop over all entries in the tree and store them in a vector
double value;
tree->SetBranchAddress("value", &value);
std::vector<double> values;
for (int entry=0; entry<tree->GetEntries(); ++entry) {
tree->GetEntry(entry);
values.push_back(value);
}
//Sort the vector of values
std::sort(values.begin(), values.end());
//Take the value every countsPerBin and use it as the bin edge.
std::vector<double> binEdges;
binEdges.push_back(values.front());
for (int edge=1; edge<numBins; edge++) {
binEdges.push_back(values.at(countsPerBin * edge));
}
binEdges.push_back(values.back());
```

thanks Ksmith for your reply ,

I use your algo but I have got this error :

Error: Function sort(values.begin(),values.end()) is not defined in current scope macro.c:19:

*** Interpreter error recovered ***

It is just an algorithm, not code for your specific case, it will need some modification. You will need to replace `"value"`

with the name of the branch you are interested, the pointer `tree`

with the pointer of your tree, and so on.

Sorry, misread your post. You need to include the algorithm header:

```
#include <algorithm>
```

Hi smith,

Could you please explain me this instruction “(values.at(countsPerBin * edge)” because I have got an error in this line

Cheers,

Souad

Sure. The at method just gets the value at the index passed to it. The idea here is that the loop goes over each bin edge and accesses the entry that is countsPerBin from the last edge. I did not add a check to ensure that the value accessed is within the size of the vector. You may need to modify the routine to perform this check.

http://www.cplusplus.com/reference/vector/vector/at/

Also, I noticed I missed a parenthesis in the original example on that line, I have corrected it.

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