# Problem when rescaling Y axis

Hi,

I am trying to rescale Y axis using the following code:

``````//Rescaling macro

#include "TAxis.h"
#include "TH1.h"
#include "TArrayD.h"

Double_t ScaleX(Double_t x)
{
Double_t v;
v = 10 * x + 100; // "linear scaling" function example
return v;
}

Double_t ScaleY(Double_t y)
{
Double_t v;
v = 20 * y + 200; // "linear scaling" function example
return v;
}

Double_t ScaleZ(Double_t z)
{
Double_t v;
v = 30 * z + 300; // "linear scaling" function example
return v;
}

void ScaleAxis(TAxis *a, Double_t (*Scale)(Double_t))
{
if (!a) return; // just a precaution
if (a->GetXbins()->GetSize())
{
// an axis with variable bins
// note: bins must remain in increasing order, hence the "Scale"
// function must be strictly (monotonically) increasing
TArrayD X(*(a->GetXbins()));
for(Int_t i = 0; i < X.GetSize(); i++) X[i] = Scale(X[i]);
a->Set((X.GetSize() - 1), X.GetArray()); // new Xbins
}
else
{
// an axis with fix bins
// note: we modify Xmin and Xmax only, hence the "Scale" function
// must be linear (and Xmax must remain greater than Xmin)
a->Set( a->GetNbins(),
Scale(a->GetXmin()), // new Xmin
Scale(a->GetXmax()) ); // new Xmax
}
return;
}

void ScaleXaxis(TH1 *h, Double_t (*Scale)(Double_t))
{
if (!h) return; // just a precaution
ScaleAxis(h->GetXaxis(), Scale);
return;
}

void ScaleYaxis(TH1 *h, Double_t (*Scale)(Double_t))
{
if (!h) return; // just a precaution
ScaleAxis(h->GetYaxis(), Scale);
return;
}

void ScaleZaxis(TH1 *h, Double_t (*Scale)(Double_t))
{
if (!h) return; // just a precaution
ScaleAxis(h->GetZaxis(), Scale);
return;
}

``````

Its name is rescaling.cc and I use the following to call it then execute my macro:

``````.L rescaling.cc
.x myRootMacro.cc
``````

the myRootMacro.cc includes these lines in the end:

``````  h->Draw();
ScaleYaxis(h, ScaleY);
h->Draw();
h->ResetStats();
``````

So far no error, but the generated histogram shows exactly the same Y axis, nothing changed. What could be the reason for that?

With this code, â€śscalingâ€ť of the Y-axis works only for TH2 and TH3 histograms.
For a TH1 histogram, only the X-axis can be â€śscaledâ€ť this way (i.e. you cannot change the â€ścontentsâ€ť of the histogram).

Thanks for the reply. So, could we maybe then accomplish it through a different way?

For instance, letâ€™s assume this code:

``````  f = new TFile("myFile.root");
if ((!f) || f->IsZombie()) {delete f; return;} // just a precaution
f->GetObject("myTree", t);
if (!t) {delete f; return;} // just a precaution
gROOT->cd(); // all newly created histograms should be placed here
h = new TH1D("h", "number of particles;A;counts", 100, 0., 55.);
h->Sumw2(kTRUE); //makes sure errors are properly handled
t->Project("h", "nParticles");
delete f; // no longer needed (automatically deletes "t", too)

integral = h->Integral();
if (integral != 0) h->Scale(100. / integral);
h->Draw()
``````

This will draw histogram from branch in a tree, then normalize to 100. But what if you want to multiply the Y-axis (counts) by a factor? To be more specific, I wrote a code to convert counts to cross sections:

``````    TFile *file = new TFile("myFile.root");
TTree *myTree= (TTree *) file->Get("myTree");
myTree->GetEntry(myTree->GetEntries()-1);
Float_t factor = myTree->GetLeaf("branch1")->GetValue()
/ myTree->GetLeaf("branch2")->GetValue();
Float_t cross_section = counts * factor;
``````

Is there a way to link these two? Sorry if it was a bit confusing.

1 Like

I think the first approach maybe is what I need. Itâ€™s working well when I choose any double, but Iâ€™m trying to multiply by a calculated factor:

``````  TFile *f;
TTree *t;
TH1D *h;

Double_t integral;
f = new TFile("myFile.root");
if ((!f) || f->IsZombie()) {delete f; return;} // just a precaution
f->GetObject("myTree", t);
if (!t) {delete f; return;} // just a precaution
gROOT->cd(); // all newly created histograms should be placed here

TTree *myTree= (TTree *) f->Get("myTree");
et->GetEntry(myTree->GetEntries()-1);
Float_t factor = myTree->GetLeaf("branch1")->GetValue()
/ myTree->GetLeaf("branch2")->GetValue();

h = new TH1D("h", "title;A;Cross section", 100, 0., 55.);
h->Sumw2(kTRUE); //makes sure errors are properly handled
t->Project("h", "branch3");
delete f; // no longer needed (automatically deletes "t", too)

h->Scale(factor);
h->Draw();
``````

I am then getting an error:

``````Error in <TRint::HandleTermInput()>: cling::InvalidDerefException caught: Trying to dereference null pointer or trying to call routine taking non-null arguments
``````

Try to (re)use the existing â€ś`t`â€ť pointer instead of creating another â€ś`myTree`â€ť pointer and add â€ś`Double_t factor;`â€ť definition in the beginning.

It is working fine now thanks. Another question if I may, I modified the code a bit to draw two branches against one another as follows:

``````{

h = new TH1D("h", "Title;x-titel;y-title", 100, 0., 200.);
t->Project("h","branch1","branch2");
h->Draw();

}
``````

Branch1 data are being drawn correctly, but branch2 (on Y axis) was drawn after some calculations which Iâ€™m not familiar with. Do you know what this method do to the second input (branch2)?

See: TTree::Draw

``````{
TH2D *h2 = new TH2D("h2", "Title;branch 1; branch 2", 100, 0., 200., 100, 0., 200.);
#if 0 /* 0 or 1 */
t->Project("h2", "branch2:branch1");
#else /* 0 or 1 */
t->Draw("branch2:branch1 >> h2", "", "goff");
#endif /* 0 or 1 */
h2->Draw("colz");
}
``````
1 Like

Thanks Wile. Iâ€™ve been trying to convert branch2 values by multiplying by a mean value (from another histo). I did:

``````  Double_t x = h->GetMean(); //to get the mean from another histo
t->Project("h2", "x * branch2:branch1");
h2->Draw();
``````

Itâ€™s however, giving this error:

``````Bad numerical expression : "x"
Info in <TSelectorDraw::AbortProcess>: Variable compilation failed: {x / branch2:branch1 ,}
``````

`t->Project("h2", TString::Format("%g * branch2 : branch1", x));`

1 Like

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