Change scale of a TH1F (energy calibration)

I’ve a TH1F, its x axis are millivolt measured by a termistor. I’ve a linear calibration:

energy [keV] = q + x[millvolt] * m

how can change the x scale of my TH1F, I’ve tried so:

min_kev = q;
max_kev = h->GetNbinsX () * m +q;
h->GetXaxis()->SetLimits(min_kev,max_kev);

it changes the scale, but it doesn’t work well. It changes only the scale, not the datas stored! How can I do it?

Use TH1::Multiply(TF1 *f1, double c1)

see: root.cern.ch/root/htmldoc/TH1.html#TH1:Multiply

Rene

[quote=“brun”]Use TH1::Multiply(TF1 *f1, double c1)
[/quote]

I’ve to rescale the x axis, not y. Although this, I don’t understand how TH1F::Multiply woks:

TF1 *f = new TF1("f","x[0]*2.",0,100);
TH1F *h = new TH1F("h","h",100,0,100);
h->SetBinContent(20,10);
h->SetBinContent(30,20);
h->Draw(); //I've 2 bin filled equally
h->Multiply(f);
h->Draw();

(20,10) go to (20,390)
(30,10) go to (30,1180)

I hope there is an explanation

OK now I understand your question. This is possible with some approximation as in principle to make a clean operation you would need to start from teh original unbinned x values. The approximation could be the following

TH1F *h; //your original histogram int nbins = h->GetXaxis()->GetNbins(); TH1F *hnew = new TH1F("hnew","title",nbins,xminnew,xmaxnew); for (int i=1;i<=nbins;i++0 { double y = h->getBinContent(i); double x = h->GetXaxis()->GetBinCenter(i); double xnew = alpha*x + beta; //your transformation hnew->Fill(xnew,y); }
You may want to look also to TH1::Rebin (case xbins != 0) and see the procedure to recmpute errors in case the original hist has errors.

Rene

[quote=“brun”]OK now I understand your question. This is possible with some approximation as in principle to make a clean operation you would need to start from teh original unbinned x values. The approximation could be the following

TH1F *h; //your original histogram int nbins = h->GetXaxis()->GetNbins(); TH1F *hnew = new TH1F("hnew","title",nbins,xminnew,xmaxnew); for (int i=1;i<=nbins;i++0 { double y = h->getBinContent(i); double x = h->GetXaxis()->GetBinCenter(i); double xnew = alpha*x + beta; //your transformation hnew->Fill(xnew,y); }
You may want to look also to TH1::Rebin (case xbins != 0) and see the procedure to recmpute errors in case the original hist has errors.

Rene[/quote]

it’s exactly the same procedure that I’m using. The problem is when alpha > 1 (a dilatation), for example with alpha=2 half bins are empty, so I must do a rebinning.

Yes this procedure is not going to create energy from vacuum.
It is up to you to figure out the right number of bins in the new histogram to avoid either empty bins or binning effects.

Rene

Hi,

I used this trick in a similar situation:

const int nbins = h1->GetXaxis()->GetNbins();
double new_bins[nbins+1];
for(int i=0; i < nbins; i++){
new_bins[i] = transform_function( h1-> GetBinLowEdge(i+1) );
}

h1->Set(nbins, new_bins);

This will of course result in uneven binwidths if your transoformation is not linear, but does not require rebinning, etc.

Cheers!

Just a small correction since I found it useful…

const int nbins = h1->GetXaxis()->GetNbins();
double new_bins[nbins+1];
for(int i=0; i <= nbins; i++){
new_bins[i] = transform_function( h1-> GetBinLowEdge(i+1) );
}

h1->SetBins(nbins, new_bins);