next up previous contents
Next: Leak Checker Up: The MINOS Off-line Software Previous: Data Model and I/O   Contents

Subsections


Ntuples

Last significant change: 2005/07/07


Introduction

An Ntuple stores data of basic data types in an easy to access format in which data variables may be manipulated, plotted and fitted. An example of an application of an ntuple is to store frequently accessed reconstruction variables, which taken together summarize the results of a reconstruction job.

The purpose of this chapter is to describe how to create and use ntuples within the MINOS framework.

Standard Ntuples (NtpSt/SR/MC/TH)

Standard Ntuples are those ntuples produced during production running as an end product of Standard Reconstruction. Each Standard Ntuple file contains one or more ntuples, each in the form of a ROOT TTree.

The ntuple trees produced during production up until R1.14 were:

These 3 ntuples were replaced in production running as of R1.14 with a single ntuple TTree: NtpSt. The NtpSt tree contains all data previously stored in the 3 separate ntuples. The 3 separate ntuples are maintained, and although not produced in production running, can still be produced in user's individual jobs.

The standard ntuples are produced through storage of NtpXXRecord objects in a root TTree of name NtpXX. The best place to look for definition of data members stored in the standard ntuples is to look at the NtpXXRecord.h and helper class header files. These files are stored in the following packages:

for the NtpSR, NtpMC NtpTH and NtpSt ntuples respectively.

For example, the definition of the cosmic ray data members stored in the NtpSR tree can be found in the CandNtupleSR/NtpSRCosmicRay.h file as:

  Float_t zenith;  // zenith angle (degrees)
  Float_t azimuth; // azimuthal angle measured easterly from north (degrees)
  Float_t ra;           // right ascension (degrees)
  Float_t rahourangle;  // right ascension (hours)
  Float_t dec;          // declination (degrees)
  Double_t juliandate;  // julian date (days since Jan 1, 4713 BC 12h UT)
  Float_t locsiderialtime; // local sidereal time (hours)

Using ntuples

Ntuple trees may be analyzed mutiple ways:

The purpose of the following sections is to introduce some approaches to analyzing ntuple data.

Analyzing ntuple data in a bare root session with TBrowser,TTree::Draw, etc.

Use of the TruthHelperNtuple

The truth helper data stored in the NtpTH tree can be used to move from the reconstructed entity (slice,shower,track) to the best match truth entries in the NtpMC tree. For example, for the first reconstructed slice in a given snarl, thslc[0].neumc will give the index of the best match initiating neutrino in the NtpMC mc array, and thslc[0].neustdhep will give the index of the best match neutrino in the NtpMC stdhep array.

Taking the example a step further, the mc.iaction associated with the first slice of a given snarl is mc[thslc[0].neumc].iaction. To select slices which satisfy the selection of best match neutrino has mc.iaction equal to 0 (neutral current), use the selection string "mc[thslc.neumc].iaction==0". The entries in thslc are implicitly looped over.

To Draw members of the slc array which satisfies this selection cut, do this:

root[0] TFile* file = new TFile("overlayfile.root","READ");
root[1] TTree* ntpsr = (TTree*)(file -> Get("NtpSR"));
root[2] TTree* ntpmc = (TTree*)(file -> Get("NtpMC"));
root[3] TTree* ntpth = (TTree*)(file -> Get("NtpTH"));
root[4] ntpmc -> AddFriend(ntpsr);
root[5] ntpmc -> AddFriend(ntpth);
root[6] ntpmc -> Draw("slc.index","mc[thslc.neumc].iaction==0");

Since slc and thslc share a common set of indices (i.e. there's a 1:1 relationship between them), this command will plot the slc indices corresponding to those with mc.iaction==0.

Analyzing ntuple data in a bare root session with MakeClass

For a user who wishes to analyze an ntuple within a bare root session without loading minos specific libraries, the TTree::MakeClass method can be a valuable tool. An example of how to do this is given here:
{
// usage: root .x scriptname.C
// The output is two files NtpSR.h and NtpSR.C

 f = new TFile("F00017566_0000.sntp.root","READ");
 t = (TTree*)(f->Get("NtpSR"));
 t -> MakeClass();
}
The execution of this example script results in two files: NtpSR.h and NtpSR.C. NtpSR.h is a header file for a new class NtpSR which reproduces the structure of the data members stored on the NtpSR tree. NtpSR.C implements the Loop method of the NtpSR class as a demonstration of how one might loop over the entries in the tree using this NtpSR class. The user may customize the Loop method implementation in NtpSR.C to suit his or her needs.

The following examples illustrate the use of the NtpSR.C script.

Analyzing ntuple data in a loon session with a script

An example of how to analyze ntuple data with a root script is given here.
{
// usage: loon sriptname.C
//
 gSystem -> Load("libCandNtupleSR.so");

 f = new TFile("F00017566_0000.sntp.root","READ");
 t = (TTree*)(f->Get("NtpSR"));
 NtpSRRecord* record = 0;
 t -> SetBranchAddress("NtpSRRecord",&record);

 // Loop over all entries in tree
 for ( int ient = 0; ient < t -> GetEntries(); ient++ ) {
   int nbytes = t->GetEntry(ient);
   cout << "Read entry, nbytes = " << ient << "," << nbytes << endl;

   // Example of Accessing header data
   cout << "snarl " << (record -> GetHeader()).GetSnarl() << endl;
   // or
   RecCandHeader& header = record -> GetHeader();
   cout << "snarl " << header.GetSnarl() << endl;
   cout << "run " << header.GetRun() << endl;

   // Example of accessing event summary data
   cout << "crhdr.azimuth " << record -> crhdr.azimuth << endl;

   // Example of accessing TClonesArray (stp,trk,etc.) data
   TClonesArray& striparray = *(record->stp);
   for ( int istp = 0; istp < striparray.GetEntries(); istp++ ) {
     NtpSRStrip* ntpstrip = dynamic_cast<NtpSRStrip*>striparray[istp];
     cout << "strip index " << ntpstrip->index << endl;
   }
   record -> Clear();  // release allocated memory, record will be reused
 }

 delete record; record = 0;

}

Analyzing data from multiple ntuple trees in parallel

Analyzing data from two or more ntuples in parallel in a root session requires making use of the TTree::AddFriend mechanism.

In the simplest use case in which the ntuple trees are aligned such that there is a 1:1 relationship between entries in the separate trees, the TTree::AddFriend method may be used directly. The following example illustrates how to do this:

{
  TFile* file = new TFile("ntuple.root","READ");
  TTree* mctree = (TTree*)(file -> Get("NtpMC"));
  TTree* srtree = (TTree*)(file -> Get("NtpSR"));

  // Make the srtree a friend of the mctree
  mctree->AddFriend(srtree);

  // It's now possible to draw data members of either tree
  // using the mctree pointer, for example:
  // mctree->Draw("evt.vtx.z");  // branch on NtpSR tree
  // mctree->Draw("mc.vtxz");   // branch on NtpMC tree
  mctree->Draw("evt.vtx.z:mc.vtxz","","box"); // plotting SR vtx vs MC vtx
}

In some cases, however, the relationship between entries in different ntuple trees is not 1:1. An example of this is the writing of non-triggering truth records to the NtpMC tree, which do not result in the writing of a corresponding entry to the NtpSR tree. In this case, the 1:1 relationship between tree entries is lost.

This loss of 1:1 relationship is not a problem within our framework, which will use the VldContext stored with the records to resynchronize the entries across the two trees when reading the NtpMC and NtpSR streams in during a subsequent loon job. But the loss of 1:1 relationship is a problem when analyzing the trees in a root session using TTree::AddFriend, since this method only matches records across two or more trees by tree index.

A future version of root should support the feature of using TTree::AddFriend to synchronize by ``key value'' (e.g. VldContext). In the meantime, a script is provided by the MINOS framework that can be used to restore the functionality of TTree::AddFriend with non-aligned trees. The script synchronizes trees by "key value", so that they can be used with the TTree::AddFriend mechanism. The script, and a second script to demonstrate its use, can be found in Record/macros as AddFriendByKey.C and AlignTreesByKey.C.


next up previous contents
Next: Leak Checker Up: The MINOS Off-line Software Previous: Data Model and I/O   Contents
MINOS Software 2013-09-02