Can we shift histogram for several channels?

Good day, everyone here!
Can anyone give me some informations about these two questions:
1)If I already have a histogram, can I shift this histogram for several channels in the X axis?
For example, when I want to calibrate the energy spectrum, E=a*chn+b, where “a” & “b” is the constants, “chn” is the original x axis, “E” is the new x axis. How can I realize that?

2)During my data analysis, I found that sometimes the cut sequence will affect the result. For instance,
A. h1->Draw(“fast:slow>>hist1”,cut2 && cut1 );
B. h1->Draw(“fast:slow>>hist2”,cut1 && cut2 );
" h1" is the tree name, “fast” & “slow” are the branch name, “hist1” &“hist2” are histogram, cut1 & cut2 are cut name.

The events statistic of these two sentences are different! It should be the same! Why the result is different?

Thanks a lot!

My email adress: draudy.won@gmail.com
MSN: draudy_won@hotmail.com

I’m not sure if this is fully kosher, but suit yourself :

#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;
}

Try:

hist1->Draw();
ScaleXaxis(hist1, ScaleX);
hist1->Draw();
ScaleYaxis(hist1, ScaleY);
hist1->Draw();

Note also that, after you “scale” the axes of your histogram, you should also “reset its statistics”:

hist1->ResetStats();

BTW. If you need to “scale” the contents of the histogram (i.e. not any of its axes), you can use:
TH1::Scale (Double_t c1 = 1, Option_t *option = "")
TH1::Multiply (TF1 *f1, Double_t c1 = 1)
TH1::Divide (TF1 *f1, Double_t c1 = 1)

5 Likes

Dear Pepe Le Pew, Thanks a lot for you help!

It is Wonderful! These codes work very well in my job!

Cheers!