Copy entries of TProfile

Hi everyone,

I’ve been having a tricky issue. I have a filled TProfile which I hope to take and crop down to only range from the first bin above 0 to the last bin above 0 (ie only a fraction of the bins are actually filled). So what I do then is find those two bins, make a new TProfile with the reduced size x-axis range (and fewer bins) and try to copy over the entries of the original TProfile to the new one. Then I hope to overwrite the old TProfile with the new one (in a .root file).
The issue is I’m not entirely sure how to go about this, I thought something like this would work (assuming h is the old TProfile, and h1 is the new one:

h = dynamic_cast<TProfile*>( f->Get(histo_name) );
Int_t min = h->FindFirstBinAbove(0);
Int_t max = h->FindLastBinAbove(0);

TProfile *h1 = new TProfile(h->GetName(),h->GetTitle(),max-min+1,h->GetBinLowEdge(min),h->GetBinLowEdge(max)+h->GetBinWidth(max),"");
Int_t j = 1;
   for(Int_t i = min; i < max+1; i++){
   h->GetBinContent(i) << ", binerror: " << h->GetBinError(i) << std::endl;
   //h1->Fill(h1->GetBinCenter(j),h->GetBinContent(i));
   h1->SetBinContent(j,h->GetBinContent(i));
   h1->SetBinError(j,h->GetBinError(i));
   j++;
}
dir->cd();
h1->Draw();
//h->Delete();
h1->Write("",TObject::kOverwrite);

but the error bars aren’t right. So my question is how do you copy bin by bin entries of a TProfile? Or, if someone has a more elegant cropping scheme, I would appreciate hearing it.

Thanks!

Hi,
to copy the bin content of profile is a bit more complicated. You need to copy all these quantities:

  • sum of bin y values
  • sum of bin y*y values
  • sum of bin weight = number of bin entries if profile is filled with weights =1
  • sum of bin weight ^2 if the profile is filled with weights different than 1

For doing this you should not use SetBinContent and SetBinError because these are TH1 methods.
Do instead if ibin is your bin number and pold a pointer to the old profile and pnew a pointer to the new one:

 TProfile * pold = ... // old TProfile
 TProfile * pnew = ... // new TProfile 
 
 int ibin = ...  // new bin number 
 int jbin = ... // old bin number 
  
 (*pnew)[ibin] = (*pold)[jbin];    // copy bin y values 
 (*pnew->GetSumw2())[ibin] =  (*pold->GetSumw2())[jbin];   // copy bin y*y values
 pnew->SetBinEntries(ibin, pold->GetBinEntries(jbin) );    // copy bin entries
// copy (if needed) bin sum of weight square
if ( pold->GetBinSumw2()->fN > jbin ) { 
   pnew->Sumw2();
   (*pnew->GetBinSumw2())[ibin] = (*pold->GetBinSumw2())[jbin];   
 }

Lorenzo

That worked!
Thanks Lorenzo!