Apply cuts on histograms

Hi,

I would like to know wether there is an automatic way to tell ROOT to make some cuts on your histograms, right now I use something like :

void   CutHisto(TH1D * histo, double xmin, double xmax)
{
  // Look for the number of bins of the histogram
  int Nbins = histo -> GetNbinsX() ;
  // fill hitograms (!! bin content is +1 ahead !!)
  for (int i=0 ; i<Nbins ; i++ )
    {
      // test to see if we are in a region that should be cut
      double x = histo -> GetXaxis()-> GetBinCenter(i) ;

      if ( (x <= xmin) || (xmax <= x) )
	{
	  histo -> SetBinContent(i+1, 0.0) ;
	  histo -> SetBinError(  i+1, 0.0) ;
	}

    }
}

But in case Idon’t want to make cuts I should use some tricks so I wanted to know if there is already something that was made. Thanks in advance for your help.

It is not clear if you want to apply your cut after having filled the histogram (just for drawing for example) or if you want to apply a cut while filling it. In the later case you just have to do

Rene

Actually I want to apply the cut after the filling for drawing/analyses.

Thanks

Again your question is not clear. Do you want to modify the bin contents following some cut expression? or do you want a drawing option keeping the bin contents unchanged, but drawing only the bins that are within the cut? The second option is currently available only for 2-d histograms (see doc of THistPainter::Paint and look for cut)

It looks like you are not aware of TTree/TNtuple. Once you have Trees,
you can specify any cut instruction in TTree::Draw.

Rene

Hi,

Thanks for your help. The thing is I have an histogram which is already filled, it is read from the disk in a ROOT file and after for my analyses I want to have the possibility to select the range of my histogrma swhere I want to perform my analyse (chi2, etc.). Does that give you a better idea ?

Since I am doing a job based on stand alone MC I am using histograms, I used in the past some hbook ntuples converted to root files but it was not the best solution for my work.

Thanks.

When you set a range on a given axis, eg with

histo->GetXaxis()->SetRangeUser(xmin,xmax); or histo->GetXaxis()->SetRange(binmin,binmax);
drawing and fitting operations will consider only the bins in the range.

Rene

1 Like

Ok thanks I will try that tomorow

Hello,

Sorry to bother you once again but your trick didn’t seemed to work, here is what I do instead. I tried to put your line at a higher level in my program but the plots are entirely drawn. Please tell me if you see what can goes wrong. If you can’t that’s ok, just give me your advice wether or not the trick to make my cut shouldn’t be a problem for the rest of the
study :

/////////////////////////////////////////////////////////////////////////////////
//                                                                             //
// CutHisto                                                                    //
//-----------------------------------------------------------------------------//
// input  : histo    : histo upon which the cuts should be applied             //
//          str_xmin : minimum cut value, do nothing if = "nocut"              //
//          str_xmax : maximum cut value, do nothing if = "nocut"              //
//                                                                             //
/////////////////////////////////////////////////////////////////////////////////
void CutHisto(TH1D * histo, string str_xmin, string str_xmax)
{

  // 1. Compute cut_case that allows to choose in which case we're in
  // ****************************************************************
  int low_cut(0), high_cut(0) ;
  if (str_xmin != "nocut") low_cut  = 1 ; // lower  cut
  if (str_xmax != "nocut") high_cut = 1 ; // higher cut
  int cut_case = 10*high_cut + low_cut  ; // binary-like values (00,01,10,11)

  // 2. Compute the DOUBLE values for xmin and xmax
  // **********************************************
  double xmin = histo -> GetXaxis() -> GetXmin() ;
  double xmax = histo -> GetXaxis() -> GetXmax() ;
  switch(cut_case)
    {
    case  0 :  // 00 : no cut
      break ;
      
    case  1 :  // 01 : low cut only
      xmin = GetNumberFromString(str_xmin) ;
      break ;
      
    case 10 : // 10 : high cut only
      xmax = GetNumberFromString(str_xmax) ;
      break ;
      
    case 11 : // 11 : both low & high cut
      xmin = GetNumberFromString(str_xmin) ;
      xmax = GetNumberFromString(str_xmax) ;
      break ;
    }

  // 3. Apply the cut
  // ****************
  // Note : The following line should work 
  //          histo -> GetXaxis() -> SetRangeUser(xmin,xmax) ;
  //        but it doesn't,... see :
  //        ROOT-talk : http://root.cern.ch/phpBB2/viewtopic.php?t=5508
  //        In the meantime we use another trick :

  // Look for the number of bins of the histograms
  int Nbins = histo -> GetNbinsX() ;
  
  // fill histograms with 0 WHEN NEEDED (!! bin content is +1 ahead !!)
  for (int i=0 ; i<Nbins ; i++ )
    {
      double x = histo -> GetXaxis()-> GetBinCenter(i) ;
      // test to see if we are in a region that should be cut out
      if ( (x <= xmin) || (xmax <= x) )
	{
	  histo -> SetBinContent(i+1, 0.0) ;
	  histo -> SetBinError(  i+1, 0.0) ;
	}
    }

}

What you do is a noop. Did you read carefully my mail above on how
to specify a range 9xmin,xm,ax) on one axis?
I do not see any calls to TAxis::setRange opr Rangeuser in your test.

Rene

Well As you can see Icommented out the part you gave since it wasn’t working :

Before I replaced the loop by the following :

But couldn’t see any differences.