Save histogram one by one ata time

Happy New year to everyone.

I have problem, trying to loop through a list of .root file, get histogram B, do calculation with histogram A, den put histograms A and B on same canvas, den save each individual canvas. Trouble is saving each individual histogram A and B for each file.

A sample of the code:

void contam_study()
{
  char const *infile = "Bgoodndst.list";
  
  TFile *file = TFile::Open("Atrigger_goodndst.root");

  TTree *tree = (TTree*)file->Get("tree");
  Int_t nevents = tree->GetEntries();
  cout << "Nevents = " << nevents << endl;
  Int_t   s_stvar;
  Float_t stvar[50];
  TBranch *s_stv_branch = tree->GetBranch("s_stvar");
  s_stv_branch->SetAddress(&s_stvar);
  TBranch *ntv_branch = tree->GetBranch("stvar");
  ntv_branch->SetAddress(&stvar);

  //histogram A abd B
  TH1F *hsq = new TH1F("hsq","bcq",100,0.,2500);
  // hsq->SetBit(TH1::kCanRebin);
  TH1F *h_sq = new TH1F("h_sq","bnsq",100,0,2500);

  
// get variables from  fileA
  for (Int_t ievt=0; ievt<n events; ievt++)
  {

    tree->GetEvent(ievt);
    float bsum =  stvar[2] + stvar[3];
    hsq->Fill(bsum);

  }//end of for loop

  //file B files one at time, den,calculate
  ifstream runlist(infile);//file stream 
  char filepath [900];
  TFile *tfile[10000];
  int nfile = 0;

  if(runlist)
  {
    while( runlist.good() )  // continue reading file
    {
      runlist.getline(filepath,900);
      if ( runlist.eof() ) break;

      tfile[nfile] = new TFile(filepath, "read");

      if ( tfile[nfile] )
      {
        tfile[nfile]->GetObject("h_sum",h_sq);
      }


   TCanvas *bb = new TCanvas("bb","A/B_sum",550,425);
   TH1 *histo = hsq->Clone("histo");
   histo->Divide(h_sq);
   TF1 *poly0 = new TF1("poly0","pol0",1800,2000);
   histo->Fit(poly0,"R");
   gPad->SetLogy(1);
   Double_t scale = poly0->GetParameter(0);
   cout << "scale =  " << scale << endl;

   THStack *hs = new THStack("hs","Stacked histogram");
   hs->Add(hsq);
   hsq->SetLineColor(4);
   hs->Add(h_sq);
   h_sq->SetLineColor(2);
   h_sq->Scale(scale);
   hs->Draw();


  tfile[nfile]->Close(); //lock di file

  nfile++;//stepwise
  }
}
else
 {
   cout << "file " << infile << " does not exist" << endl;
}
    
  //fi save indiv  plots
  TFile *h = new TFile("outfile.root", "RECREATE");
  h->cd();
  hs->Write();//fi di individual files out.

  runlist.close();//close list file.

}//end of void

Awaits your kind assistance.
Cheers
Prya13

Move this

TFile *h = new TFile("outfile.root", "RECREATE");

to just before the creation of hsq and h_sq (TH1F *hsq = new TH1F…), and move these two

  h->cd();
  hs->Write();

inside the while loop over runlist, just after hs->Draw();
Since you are saving many different hs stacks, you should give them different names, e.g. something like

  hs->Write(Form("hs%d",nfile));

instead of Write().
And don’t forget to close the root file at the end of your macro

  h->Close();
  delete h;

Hello @Prya13,

Thanks @dastudillo for contributing! If the answer provided by @dastudillo does not solve your issue, feel free to ask again.

Cheers,
J.

Thank you so much dastudillo, for your response.
The file are been saved individually but I am seeing the two different histogram, not sure what is happening now. Here is an example:

Cheers
Priya

Jalopezg,

Thank you for your response. Dastudillo helped marvelously, now I have another issue regarding the outcome of the plots.

Cheers,
Prya13

Dear All,

I have another concern regarding the same macro above, I am trying to reset the THStack in the loop each time I draw before moving on to the next file.

hs->Reset();
but I got error: Can’t call THStack::Reset(), how can I reset the THStack each time?
Can you kindly make me suggestions to fix this error?

Cheers
Prya

hs->GetStack()->Clear();

Should do it.

Check the THStack doc. THStack doesn’t have a such method.

Thank you for your response, however I got error Can’t call GetStack()

THStack::GetStack exists.
Can you post the script producing this error ?

I am using the same script at the top of this thread, only added hs->Reset() and the modifications from dastudilllo.

If you show the code people can give better help by seeing what exactly you are trying; as you know from my first answer, it’s not only the commands you use but where they are. Where are you trying to call GetStack? Maybe try doing it before closing tfile[nfile]?

Reset does not exist for THStack … post your code please.

Thank you so much. This is the macro using:

void contam_study()
{
  char const *infile = "Bgoodndst.list";
  
  TFile *file = TFile::Open("Atrigger_goodndst.root");

  TTree *tree = (TTree*)file->Get("tree");
  Int_t nevents = tree->GetEntries();
  cout << "Nevents = " << nevents << endl;
  Int_t   s_stvar;
  Float_t stvar[50];
  TBranch *s_stv_branch = tree->GetBranch("s_stvar");
  s_stv_branch->SetAddress(&s_stvar);
  TBranch *ntv_branch = tree->GetBranch("stvar");
  ntv_branch->SetAddress(&stvar);


   TFile *h = new TFile("outfile.root", "RECREATE");
  //histogram A abd B
  TH1F *hsq = new TH1F("hsq","bcq",100,0.,2500);
  // hsq->SetBit(TH1::kCanRebin);
  TH1F *h_sq = new TH1F("h_sq","bnsq",100,0,2500);
  THStack *hs = new THStack("hs","Stacked histogram");

  
// get variables from  fileA
  for (Int_t ievt=0; ievt<n events; ievt++)
  {

    tree->GetEvent(ievt);
    float bbcnq= stvar[2];
    float bbcsq= stvar[3];
    float bsum =  bbcnq + bbcsq;

    hsq->Fill(bsum);
  }//end of for loop

  //file B files one at time, den,calculate
  ifstream runlist(infile);//file stream 
  char filepath [1000];
  TFile *tfile[10000];
  int nfile = 0;

  if(runlist)
  {
    while( runlist.good() )  // continue reading file
    {
      runlist.getline(filepath,1000);
      if ( runlist.eof() ) break;

      tfile[nfile] = new TFile(filepath, "read");

      if ( tfile[nfile] )
      {
        tfile[nfile]->GetObject("h_sum",h_sq);
      }


   TCanvas *bb = new TCanvas("bb","A/B_sum",550,425);
   TH1 *histo = hsq->Clone("histo");
   histo->Divide(h_sq);
   TF1 *poly0 = new TF1("poly0","pol0",1800,2000);
   histo->Fit(poly0,"R");
   gPad->SetLogy(1);
   Double_t scale = poly0->GetParameter(0);
   cout << "scale =  " << scale << endl;

  //reset each histogram each time goes through the loop
   hs->GetStack()->Clear();
   hs->Add(hsq);
   hsq->SetLineColor(4);
   hs->Add(h_sq);
   h_sq->SetLineColor(2);
   h_sq->Scale(scale);
   hs->Draw();
   gPad->SetLogy(1);//plotting log
   gPad->Update();//updating camvas each time



   h->cd();
   hs->Write(Form("hs%d",nfile));//fi di individual files out.
        
        
  tfile[nfile]->Close(); //lock di file

  nfile++;//stepwise
  }
}
else
 {
   cout << "file " << infile << " does not exist" << endl;
}
    
  //fi save indiv  plots
  
  runlist.close();//close list file.

}//end of void

Are you sure you ran this macro ? there is a typo on the line:

  for (Int_t ievt=0; ievt<n events; ievt++)

I removed the extra space…

Also on this line there is a mistake:

   TH1 *histo = hsq->Clone("histo");

it should be:

   TH1 *histo = (TH1*)hsq->Clone("histo");

having done that changes the macro compiles but I am missing your data files in order to run it.

Couet,
Thank you so much for your assistance.
Yes the macro runs however the line: hs->GetStack()->Clear(); gives error: Error: illegal pointer to class object GetStack() 0x0 70

If I comment it out no error but histograms is overlaying each other on each turn through the loop but I would like to reset the hs each time through the loop.

I don’t know how to reset the THStack on each turn, can you kindly suggest me?
Cheers

Move that line after hs->Write(...), or try

   if (nfile>0) hs->GetStack()->Clear();

dastudillo,

Thank you for your assistance, tried both way but no solution still. Plots still overlapping on each other.

Ok, can you provide your data files so we run your macro ?