How do you fill Histograms from Chains?

Hello,

I am very new to ROOT and I am trying to write an analysis macro.

In “interactive mode” I can create a chain, add the data files with the same TTree name to the chain, create a histogram, and then draw the leaves in it that I want with a command like this:

chain.Draw(“leafname>>h1”);

After drawing it, I can then analyze the bins however I need to. But if I write this inside a macro file, it neither fills nor renders the histogram, and I would like to perform the analysis without Draw anyway. I would like to be able to just fill the histogram from a chain in my analysis loop. How do I do this? The manuals discuss creating “Events” but I get errors when I try to use the “Event” type in interactive mode. Is there another way?

Hi,

Please re-read the User’s Guide chapter on TTrees. Instead of TTree::Draw, you can use TTree::MakeSelector or TTree::MakeProxy. The result of both we will give a code skeleton that can be used for the analysis and/or for inspiration in writing your own analysis.

[quote]The manuals discuss creating “Events” but I get errors when I try to use the “Event” type in interactive mode. [/quote]‘Event’ is only an example/tutorials class (which has an implementation in $ROOTSYS/test). You should be using your own object class instead of Event.

[quote] But if I write this inside a macro file, it neither fills nor renders the histogram[/quote]It should have fill (and rendered it if not in batch mode), you must have change something else when moving from command line to script. (can’t tell more without a concrete example).

Also please note that since TChain inherits from TTree, a chain can be used anywhere a TTree is used.

Cheers,
Philippe.

Well I have most of the analysis written, I am just looking for the command that will fill a histogram. I seem to be unable to do this from a macro inside of a loop.

Here is basically my code for this one:

The first draw command does not generate anything, and as you can see creates all zeroes when I try to read the bin values later. I would like to just instruct it to fill the histogram without creating a graphic, but I can’t seem to get it to work with the TTree fill command either. Is it the same?

Hi,

You code snippets seems okay … the problem must be somewhere else (chain definition, name of the variable, etc.). Can you provide a complete running example (this would enable us to diagnose the real problem)?

Cheers,
Philippe.

If I run this code and truncate it after the draw command, the graphic displays. However, adding everything else causes it to fail the draw as well as the fill.

[quote]#include <TMath.h>
#include <Riostream.h>
#include

void CobaltUnfolder() {

gROOT->Reset();

TChain chain("DetectorTree");                                 
chain.Add("cobaltsim_det.root");                              
chain.Add("cobaltsim_det_1.root");                            
TH1F *E1 = new TH1F("E1","Folded Co 60 Spectrum",2600,0,2600);
TH1F *E2 = new TH1F("E2", "Unfolded Co 60 Spectrum", 2600, 0, 2600);
TF1 *unfolder = new TF1("unfolder","gaus");	
chain.Draw("fEdep>>E1");

for (int i = 0; i < 2600; i++) {
	double binContent = E1->GetBinContent(i);
	cout << binContent << "\n";   <- diagnostic
	resolution(i);
	cout << resolution(i) << "\n";   <- diagnostic
	E2.FillRandom("unfolder",binContent);
}

E2->DrawCopy();

}

double resolution(int x) {
return 1.5+ .001*x;
}[/quote]

Hi,

The following should work:

[code]#include <TMath.h>
#include <Riostream.h>
#include

void CobaltUnfolder() {

TChain chain(“DetectorTree”);
chain.Add(“cobaltsim_det.root”);
chain.Add(“cobaltsim_det_1.root”);
chain.LoadTree(0);
TH1F *E1 = new TH1F(“E1”,“Folded Co 60 Spectrum”,2600,0,2600);
TH1F *E2 = new TH1F(“E2”, “Unfolded Co 60 Spectrum”, 2600, 0, 2600);
TF1 *unfolder = new TF1(“unfolder”,“gaus”);
chain.Draw(“fEdep>>E1”);

for (int i = 0; i < 2600; i++) {
double binContent = E1->GetBinContent(i);
cout << binContent << “\n”; <- diagnostic
resolution(i);
cout << resolution(i) << “\n”; <- diagnostic
E2.FillRandom(“unfolder”,binContent);
}

E2->DrawCopy();
}

double resolution(int x) {
return 1.5+ .001*x;
}[/code]

Cheers,
Philippe.

After displaying the first histogram, I get this error:

[quote]Error: G__getvariable: expression CobaltUnfolder.C:19:
(const int)0
*** Interpreter error recovered ***[/quote]

Line 19 is “resolution(i);” which seems unrelated as that method has been working.

I imagine “const int 0” is related to the previous error of the getbin returning no result.

Hi,

Most the definition of resolution towards the beginning of the file.

Cheers,
Philippe.

I am still getting the same error. I am trying to run this as a .C file, in case that matters.

[quote]Error: G__getvariable: expression CobaltUnfolder.C:23:
(const int)0
*** Interpreter error recovered ***[/quote]

This method worked fine before, why would it be a problem now?

Hi,

Humm … remove the text like ‘<- diagnostic’

Cheers,
Philippe.

Thank you very much for your help!

This solved my problems :slight_smile:

Hi everybody!

I have an error like this but I can’t see where is the error could anyone help me?

###code root version 5.34.36

#include "TROOT.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TTree.h"
#include "TGraph.h"
#include "TBrowser.h"
#include "TH1.h"
#include "TF1.h"
#include "TH2.h"
#include "TRandom.h"
#include "TStopwatch.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

void anaGam1(){  /// fecha linha 175
Int_t mm=0;

// read a tree already done

      // defined a chain and added

     TChain fChain("Samp3"); //samp.geom
      
      fChain.Add("Samp3_tree_1000.root"); //*/

       /*TChain fChain("Samp4"); //samp1.geom
      
      fChain.Add("Samp4_tree_1000.root"); */
            
     // if (!t) { delete f_gamos; continue; } // just a precaution

	//chain.Print();
// definition of variables	
	Int_t n_entries=0, EventID=0;
	Double_t EventAEnerDep=0.0, EventAEnerLost=0.0, EventInitKinEn;
	
	std::vector<int> *StepNumber=0;
 	std::vector<int> *StepEventID = 0;
	std::vector<double> *StepFinKinEn=0;
	std::vector<double> *StepInKinEn=0;
	std::vector<double>  *StepAcEnDep=0;
   	std::vector<double>  *StepAcEnLost=0;

   	std::vector<double>  *StepFinPosX=0;
   	std::vector<double>  *StepFinPosY=0;
   	std::vector<double>  *StepFinPosZ=0;
	std::vector<string> *StepFinLogVol;//=0;
	std::vector<string> *StepInitLogVol;//=0;   
	std::vector<string> *StepParticle;

// carry out the same variables defined	

  fChain.SetBranchAddress("Event_EventID",&EventID);
  fChain.SetBranchAddress("Event_AccumulatedEnergyDeposited",&EventAEnerDep);
  fChain.SetBranchAddress("Event_AccumulatedEnergyLost",&EventAEnerLost);
  fChain.SetBranchAddress("Event_InitialKineticEnergy",&EventInitKinEn);
  
  fChain.SetBranchAddress("Step_StepNumber", &StepNumber);
  fChain.SetBranchAddress("Step_EventID",&StepEventID);
  fChain.SetBranchAddress("Step_AccumulatedEnergyDeposited",&StepAcEnDep);
  fChain.SetBranchAddress("Step_AccumulatedEnergyLost",&StepAcEnLost);
  fChain.SetBranchAddress("Step_Particle",&StepParticle);

  fChain.SetBranchAddress("Step_FinalKineticEnergy",&StepFinKinEn);
  fChain.SetBranchAddress("Step_InitialKineticEnergy",&StepInKinEn);
  fChain.SetBranchAddress("Step_FinalLogicalVolume", &StepFinLogVol);
  fChain.SetBranchAddress("Step_InitialLogicalVolume", &StepInitLogVol);
  fChain.SetBranchAddress("Step_FinalPosX", &StepFinPosX);
  fChain.SetBranchAddress("Step_FinalPosY", &StepFinPosY);
  fChain.SetBranchAddress("Step_FinalPosZ", &StepFinPosZ);

 
///////////////// fill histogram and load tree

  int nbins = 200;
  gStyle->SetOptStat(1111111);
  TCanvas * c1 = new TCanvas("c1", "c1", 800, 600);
  TH2F *histo3 = new TH2F("histo3", "histo3", nbins, -1.5, 1.5, nbins, 0., 0.0455); // hist->Samp2 (samp1.in) 0.05  0., -1.5, 1.5,
  //TH2F *histo4 = new TH2F("histo4", "histo4", nbins, -1.5, 1.5, nbins, 0., 0.0455); // hist1-> Samp1 (samp.in) 0.025

  

	Long64_t nb = 0, nbytes = 0;
	n_entries=fChain.GetEntries();
	for (Int_t j=0; j<n_entries;j++){ //run in all tree //////fecha linha 160
		
    		nb = fChain.GetEntry(j); nbytes += nb;

                //cout<<"file= "<<i<<endl;
		cout<<"entries vector = "<<n_entries<<endl;
		//cout<<"entries vector 1 = "<<fChain.GetEntriesFast()<<endl;
		cout<<"nbytes = "<<nbytes<<endl;
		//cout<<""<<
		cout<<"Entry = "<<j<<endl;
		cout<<"size = "<<StepFinLogVol->size()-1<<endl;

		//cout<<"EventID = "<<EventID<<endl;
		
//		cout<<"EventAEnerDep = "<<EventAEnerDep<<endl;
//	        cout<<"EventAEnerLost = "<<EventAEnerLost<<endl;
//		cout<<"StepEventID = "<<StepEventID->size()<<endl;
//		cout<<"StepFinKinEn = "<<StepFinKinEn->size()<<endl;

		//cout<<"Value Vol(before) = "<<StepFinLogVol->at(i)<<endl;
          for(Int_t i=0; i<n_entries;i++){
		if(StepFinLogVol->size()!=0){ //load the branches of the tree ///fecha linha 158
			Int_t contador=0;
			cout<<endl;

			while (StepFinLogVol->at(contador) !="control" && contador < StepFinLogVol->size()-1){ /// fecha linha 137
				contador++;

			      	//hist ->Fill(StepFinKinEn->at(contador)); 
	    			/*cout<<"entry vector = "<<contador<<endl;
				cout<<"volume = "<<StepFinLogVol->at(contador)<<endl;
		      		//hist ->Fill(StepFinKinEn->at(contador)); 
				cout<<"StepInKinEn = "<<StepInKinEn->at(contador)<<endl;

				cout<<"StepFinKinEn = "<<StepFinKinEn->at(contador)<<endl;
				cout<<endl;
				cout<<"#####"<<endl;

				cout<<"EnLost by Step = "<<StepInKinEn->at(contador)-StepFinKinEn->at(contador)<<endl;
				
				cout<<"StepAcEnLost = "<<StepAcEnLost->at(contador)<<endl;*/

			}

			Double_t sum=0;
			if (StepFinLogVol->at(contador) !="control") { // fecha linha 148
				
				for(Int_t l=0;l<StepNumber->size();l++){ /// fecha linha 144
					sum = sum + StepAcEnLost->at(l);
				} 
				//hist1 -> Fill(sum); //enter in control
				//hist -> Fill(StepAcEnLost->at(contador));
				//hist -> Fill(EventAEnerLost); //deu certo!! 
			}

			if (StepFinLogVol->at(contador) =="control" && StepParticle->at(contador) != "e-") {//linha 154
				mm++; 
				cout<<"cont = "<<contador<<endl;
				histo3 -> Fill(StepFinKinEn->at(contador),StepFinPosX->>at(contador));
			}
			
			cout<<endl;
                             
		}
            }
	}
cout<< "numero de partículas no controlo =  "<< mm<<endl;

histo3 -> SetNameTitle("energy", "FinKinEn;EKin;Counts"); //Kinetic Energy Energy Lost
histo3 -> SetFillColor(0); 
histo3 -> Draw("");

//TFile *file5 = new TFile("histo4.root", "RECREATE"); // Samp2
TFile *file4 = new TFile("histo3.root", "RECREATE");

histo3->Write();

}

Thanks

Hi David,
this is a post from 2009! Please open a new thread to get help with your issue.

Cheers,
Enrico