Find the number of entries in a TTree satisfying conditions

Hi,

I want to get the number of entries in a TTree that satisfy specific conditions.

I can use:

Example:

where T is the name of my Tree, ESi is the name of my branch, and I only want entries that are alphas in detector 56.

When I do this the spectra is drawn and the number of entries is displayed on the spectra and at the command line. For my example the number of entries happens to be 1308. I would like to get this number directly from the tree, without having to Draw or Project, such as using a function of the form like GetEntries(ā€œBranchNameā€,ā€œConditionsā€) that would return an integer.

After reading through Chapter 12 on TTrees (which was extremely helpful creating and using my first TTree :smiley: ) and looking through the description of TTree:
http://root.cern.ch/root/html508//TTree.html

I found a GetEntries(), which gives the total number of entries in the tree, but doesn’t allow for (ā€œBranchā€,ā€œConditionsā€). There is a Scan("Branch","Conditions"), which gives a list of entries satisfying the conditions. But I don’t see any functions that do what I want. Is there something I can do to get the entries with conditions from the TTree?

Further Info:

I’m using ROOT version 3.05/04.

The reason I want to get the number of entries with the specified conditions is I want to know the yield of each nuclide in each detector and with isotopic resolution to Oxygen, I have 25 possible nuclides for each of 68 detectors. Since I have so many yields to calculate I’d like something more automated, then having to draw each spectra and read off the number of entries. (Plus I have 11 other systems to calculate yields from). If there is something that could return an integer I can just loop over detectors and then over nuclei and write out the yield file.

Thanks for any ideas,

August

An easy way to do it is (untested)

tree->Draw("ESi>>hist","Det==56 && Z==2 && A==4"); 
TH1F *hist = (TH1F*)gDirectory->Get("hist"); // or get hnew from the current Pad
Int_t hist = hist->GetEntries();

This is documented in the Users Guide section Accessing the Histogram in Batch Mode.

int N = tree->Draw(ā€œESi>>histā€,ā€œDet==56 && Z==2 && A==4ā€,ā€œgoffā€);

N will contain the number of entries passing the condition and you will not get any graphics.

Rene

1 Like

Hi,

Note that the last 2 solution actually give the number of entries in the histograms and not the number of ā€˜events’ that pass the cut.
Those 2 numbers can be different if your cut expression refers to an array or collections and more than one of those elements per event passed the cut.
If you do have a collection and want to know the number of event that contains at least one match, you need to generate a TEventList and get its number of elements.

tree->Draw(">>eventlist","Det==56 && Z==2 && A==4","goff"); Int-t N = eventlist->GetN();Cheers,
Philippe.

Thanks for the help!

pcanal[quote]
Those 2 numbers can be different if your cut expression refers to an array or collections and more than one of those elements per event passed the cut.
[/quote]
That’s good to know for the future, currently I’m not using arrays.

I now have the code somewhat working, but it crashes when there are no events in the cut? However when I Draw or Project just that spectra in a root session it just creates a blank spectra and nothing crashes?

Here is my code:

    {
    // Get ROOT ready
    gROOT->Reset();
    
    char System[10]; // #, where # is between 1 and 12
    char Detector[10]; // S#D#, where # is between 1 and 12 for S and 1 and 68 for D
    char Name[50], Title[50]; // Varies
    char Parameters[200]; // Varies

    cout<<"What System?"<<endl;
    cin>>System;
    cout<<"Using System "<<System<<"\n";
    
    // Start the clock
    gBenchmark -> Start("Time");
    
    // Insert your TTree filename here: (ie. MyTTree.root)
    // Must use new here to keep the objects alive when leaving this function
    TFile *f = new TFile("MyTTree.root");
    f.ls();
    TTree *T = (TTree*)f->Get("T");
    T->Print();
        
    // Define new ROOT file for created spectra
    TFile *ff = new TFile("SpectraSi.root","RECREATE");

    // Define an output file for yield info
    ofstream Yield("IsotopicYields.dat");
    
    // Open file containing which nuclides could exist for each detector
    FILE *fi = fopen("TotalGate.txt","r");
    int GateNumber;
    char GateName[10];
    int Z, A;

    // Loop over detectors
    for(int i=1; i<69; i++)
        {
        sprintf(Detector,"S%sD%d",System,i);
        TDirectory *dir = ff->mkdir(Detector); // Make detector directory in SpectraSi.root
        dir->cd();
        cout<<"Inside "<<Detector<<endl;
        fscanf(fi,"%d",&GateNumber); // Read in the number of gates for the detector
        cout<<"Detector "<<i<<" has "<<GateNumber<<" gates"<<endl;
        Yield<<"Detector "<<i<<"\n";
        // Loop over gates
        for(int ii=0; ii<GateNumber; ii++)
             {
             fscanf(fi,"%s%d%d",&GateName,&Z,&A); // Read in Gate Name, Z and A of Gate
             cout<<i<<" "<<GateName<<" "<<Z<<" "<<A<<endl;
             // Only using isotopic gates (Z only gates have negative A values)
             if(A>0)
                 {		
                 sprintf(Name,"S%sD%dZ%dA%d",System,i,Z,A);
                 sprintf(Title,"Detector %d: Z = %d, A = %d Energy Spectra",i,Z,A);
                 sprintf(Parameters,"Det == %d && Z == %d && A == %d && Flag == 3",i,Z,A);
                 int N = T->Draw("ESi>>hist",Parameters,"goff");
                 cout<<"N = "<<N<<"\n";
                 Yield<<"    "<<Z<<" "<<A<<" "<<N<<"\n";
                 TH1F *hi = new TH1F(Name,Title,800,0.,800);
                 hi->GetXaxis()->SetTitle("E (MeV)");
                 hi->GetYaxis()->SetTitle("Yield");
                 T->Project(Name,"ESi",Parameters);
                 hi->Write();
                 }
         }
    }
    
    // Close the root file
    ff->Write();
    ff->Close();
    fclose(fi);
    Yield.close();
    
    // Stop the clock
    gBenchmark -> Show("Time");
    }

This is the output I get:

root [2] .x SpectraSi.C
What System?
1   
Using System 1
TFile**         MyTTree.root    
 TFile*         MyTTree.root    
  KEY: TTree    T;1     Data from phystapereduced.dat
******************************************************************************
*Tree    :T         : Data from phystapereduced.dat                          *
*Entries :   722075 : Total =        26060958 bytes  File  Size =   11032097 *
*        :          : Tree compression factor =   2.36                       *
******************************************************************************
*Br    0 :Event     : Mult/I:Ztot/I:Atot/I:Flag/I:Det/I:Z/I:A/I:ESi/F:ECsI/F *
*Entries :   722075 : Total  Size=   26060622 bytes  File Size  =   11023523 *
*Baskets :      814 : Basket Size=      32000 bytes  Compression=   2.36     *
*............................................................................*
Inside S1D1
Detector 1 has 14 gates
1 1He4 2 4
N = 1275
1 1H 1 -1
1 1He 2 -1
1 1Li 3 -1
1 1Be 4 -1
1 1B 5 -1
1 1C 6 -1
1 1N 7 -1
1 1O 8 -1
1 1F 9 -1
1 1Ne 10 -1
1 1Na 11 -1
1 1Mg 12 -1
1 1Al 13 -1
Inside S1D2

And everything continues until S1D57 Be7, which happens to have 0 entries for that cut, and ROOT gives a segmentation violation:

Inside S1D57
Detector 57 has 22 gates
57 57H1 1 1
N = 107
57 57H2 1 2
N = 49
57 57H3 1 3
N = 35
57 57He3 2 3
N = 6
57 57He4 2 4
N = 103
57 57He6 2 6
N = 1
57 57Li6 3 6
N = 1
57 57Li7 3 7
N = 3
57 57Li8 3 8
N = 1
57 57Be7 4 7


 *** Break *** segmentation violation
 Generating stack trace...
 0x401c7c17 in TUnixSystem::StackTrace(void) + 0x25b from /home/sjygroup/new/lib/libCore.so.3.05
 0x401c676e in TUnixSystem::DispatchSignals(ESignals) + 0xb2 from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x401c593b in <unknown> from /home/sjygroup/new/lib/libCore.so.3.05
 0x401c94d9 in <unknown> from /home/sjygroup/new/lib/libCore.so.3.05
 0x40d298d5 in <unknown> from /lib/i686/libpthread.so.0
 0x40dc9848 in <unknown> from /lib/i686/libc.so.6
 0x40bcaafc in TTree::Draw(char const *, char const *, char const *, int, int) + 0x50 from 

/home/sjygroup/new/lib/libTree.so.3.05
 0x40be3c3c in <unknown> from /home/sjygroup/new/lib/libTree.so.3.05
 0x405ba0ea in G__exec_asm + 0x8ee from /home/sjygroup/new/lib/libCint.so.3.05
 0x405ac29d in G__exec_loop + 0x53d from /home/sjygroup/new/lib/libCint.so.3.05
 0x405ac794 in G__exec_for + 0x2b4 from /home/sjygroup/new/lib/libCint.so.3.05
 0x405af722 in G__exec_statement + 0x2c96 from /home/sjygroup/new/lib/libCint.so.3.05
 0x40543ba7 in G__exec_tempfile_core + 0x2f3 from /home/sjygroup/new/lib/libCint.so.3.05
 0x40543d86 in G__exec_tempfile + 0x22 from /home/sjygroup/new/lib/libCint.so.3.05
 0x405b7de4 in G__process_cmd + 0x4a54 from /home/sjygroup/new/lib/libCint.so.3.05
 0x40175e4e in TCint::ProcessLine(char const *, TInterpreter::EErrorCode *) + 0x9a from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x40175f3c in TCint::ProcessLineSynch(char const *, TInterpreter::EErrorCode *) + 0x48 from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x401097ee in TApplication::ProcessFile(char const *, int *) + 0x6e2 from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x40108f58 in TApplication::ProcessLine(char const *, bool, int *) + 0x4ec from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x40ce9567 in TRint::HandleTermInput(void) + 0x127 from /home/sjygroup/new/lib/libRint.so.3.05
 0x40ce8890 in TTermInputHandler::Notify(void) + 0x28 from /home/sjygroup/new/lib/libRint.so.3.05
 0x40cf8a43 in TTermInputHandler::ReadNotify(void) at 

/usr/src/build/40453-i386/BUILD/glibc-2.2.4/stdlib/atexit.c:33 from 

/home/sjygroup/new/lib/libRint.so.3.05
 0x401c6b63 in TUnixSystem::CheckDescriptors(void) + 0x113 from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x401c6276 in TUnixSystem::DispatchOneEvent(bool) + 0x112 from 

/home/sjygroup/new/lib/libCore.so.3.05
 0x4014e5c5 in TSystem::InnerLoop(void) + 0x1d from /home/sjygroup/new/lib/libCore.so.3.05
 0x4014e55a in TSystem::Run(void) + 0x7e from /home/sjygroup/new/lib/libCore.so.3.05
 0x40109b65 in TApplication::Run(bool) + 0x31 from /home/sjygroup/new/lib/libCore.so.3.05
 0x40ce90a6 in TRint::Run(bool) + 0x2ba from /home/sjygroup/new/lib/libRint.so.3.05
 0x08048842 in main + 0x52 from /home/sjygroup/new/bin/root.exe
 0x40db7507 in __libc_start_main at 

/usr/src/build/40457-i686/BUILD/glibc-2.2.4/csu/../sysdeps/generic/libc-start.c:129 from 

/lib/i686/libc.so.6
 0x08048711 in __register_frame_info + 0x39 from /home/sjygroup/new/bin/root.exe
Root > 

When I just draw or project ROOT does not segment:

root [0] TFile *f = new TFile("MyTTree.root")                     
root [1] TTree *T = (TTree*)f->Get("T");                          
root [2]  T->Draw("ESi","Det == 57 && A == 7 && Z == 4")          
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
(Int_t)0
root [3] TH1F *hist = new TH1F("hist","Title",800,0.,800);        
root [4]  T->Project("hist","ESi","Det == 57 && A == 7 && Z == 4")
(Int_t)0
root [5] 

Any ideas on what would cause this crash?

Thanks,

August

Hi,

There is nothing obviously wrong in your code, so I suppose that you hit a problem in this relatively old version of ROOT (2.5 year old).
According to your describing you probably can work around the problem by simply using:if (N>0) T->Project(Name,"ESi",Parameters);
Alternatively your could try the latest production release (5.10/00) and if you can still reproduce the problem in that version please send me a way to reproduce the problem so that we can solve it.

Cheers,
Philippe.

Hi,

Even with the correction

the code still crashes. I updated to 5.10/00 and now it runs and gives 0’s instead of crashing :smiley:

Thanks!!

August