Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

H1 Specific Extensions of the SFH Package

H1's object oriented software has a very intricate data structure, based on a variant of RooT trees called H1Tree. H1 data is stored in 3 different layers, called HAT, mODS (micro ODS), and ODS (Object Data Store).

To allow easy access to the data stored on HAT and ODS, the SFH package provides additional classes derived from FloatFun, IntFun, and FillIterator, plus a set of predefined variables that can be used to immediately access large parts of the available data.

These classes are declared in jbltools/sfh/h1/H1Funs.h, the predefined variables for HAT access are in jbltools/sfh/h1/H1HATVariables.h, and the variables for mODS access are in jbltools/sfh/h1/H1ModsVariables.h.

HAT Access

File jbltools/sfh/h1/H1HATVariables.h declares a full set of variables that allow easy access to all HAT variables (currently of H1OO version 2.6.3). For a variable "Xxx" (e.g., "RunNumber", "Iclass", "Il1ac", "Epz", or "Q2da"), there exists a variable Hat_Xxx (e.g., Hat_RunNumber, Hat_Iclass, Hat_Il1ac, Hat_Epz, or Hat_Q2da).

Depending on whether the variable concerned is of an integer type (char/byte, short, int) or of floating point type (float or double), the corresponding variable is either a IntFun or a FloatFun.

Such variables can immediately be used like this:

#include "jbltools/sfh/h1/H1HatVariables.h"
DataLoop::DataLoop()
{
   SFH1F *hRunNumber = new SFH1F ("RunNumber", "RunNumber", 100, 300000., 400000., this, 
                                  Hat_RunNumber.Float());
   SFH1F *hQ2da      = new SFH1F ("Q2da", "Q2da", 100, 0., 100., this,  
                                  Hat_Q2da);
   SFH1F *hEpz       = new SFH1F ("Epz", "Epz", 100, 0., 100., this,  
                                  Hat_Epz);
}
To be used as a FloatFun, a ".Float()" must be appended to the IntFun type objects.

For array type data, like subtrigger information in Hat_Il1ac, we have defined an operator[] that can be used like this:

#include "jbltools/sfh/FillIterators.h"
#include "jbltools/sfh/h1/H1HatVariables.h"
DataLoop::DataLoop()
{
  // An iterator that loops from 0 to 127
  FillIterator& st_iter = *new RangeIterator (0, 127);
  // A histogram that shows how often raw subtriggers 0 to 127 have fired
  SFH1F *h_rwst = new SFH1F ("l1rw",  "Raw Subtriggers", 128, -0.5, 127.5, this, 
                             st_iter.Float(), Hat_Il1rw[st_iter]==1, 0, st_iter);
  // A histogram that shows Q2 for ST9 events                            
  SFH1F *h_q2   = new SFH1F ("Q2",  "Q2(DA), ST9", 100, 0., 100., this, 
                             Hat_Q2da, Hat_Il1ac[9]==1);
}  

The operator[] actually returns an object (of a subclass of FloatFun or IntFun), so we could also write

  IntFun&  Hat_Il1ac[st_iter];
  IntFun&  Hat_Il1ac[9];
  BaseCut& Hat_Il1ac[st_iter]==1;
  BaseCut& Hat_Il1ac[9]==1;

mODS Access

The access to mODS is a bit more complicated, because a large part of the mODS information is stored in H1ClonesArray objects, and because all the different particles or pseudo-particles belong to different classes.

However, to make a few simple things simple, we have defined a number of predefined variables in file jbltools/sfh/h1/H1ModsVariables.h.

For once, there exist objects that represent the number of particle candidates in the different arrays; these are called mods_NumParticles, mods_NumFNCPart, etc., and are basically of type IntFun.

These numbers are, however, not very interesing, especially, because equivalent HAT variables exist anyway.

Additionally, we have defined iterators over these arrays, with names like mods_Particles, mods_FNCPart, etc.

These iterators are of a special type, so that they can return function objects that give you basic quantities like momentum P, transverse momentum Pt, Mass, etc. These methods have the same names as in class H1Part:

\code
#include "jbltools/sfh/h1/H1ModsJpsi.h"
DataLoop::DataLoop()
{
  // A histogram that shows the mass of all J/psi candidates
  SFH1F *h_mass = new SFH1F ("jpsimass",  "J/psi mass", 40, 2., 4., this, 
                             mods_JPsi.GetMass());
  // A histogram that shows the pt distribution of all tracks   
  // with 20 deg < theta < 160deg:                  
  SFH1F *h_pt   = new SFH1F ("pt",  "Track pt", 100, 0., 10., this, 
                             mods_SelectedTracks.GetPt(),
                             20 < 57.2958*mods_SelectedTracks.GetTheta() < 160);
}  

Additionally, one can use access methods that are specific to the H1Part subclass under consideration like this:

  SFH1F *h_t    = new SFH1F ("jpsit",  "J/psi t", 40, 0., 1., this, 
                             mods_JPsi.Float(&H1PartJpsi::Get_t));
}  

The predefined iterators have a method Float() that returns a FloatFun object which uses an access methyod (in our case H1PartJpsi::Get_t()).

More complicated things, like cuts on the properties of J/psi decay particles, will, however, involve the writing of your own cut classes, for example:

#include "jbltools/sfh/BaseCut.h"
#include "H1Mods/H1PartSelTrack.h"
#include "H1Mods/H1PartJPsi.h"
#include "H1Mods/H1PartJPsiArrayPtr.h"
#include "H1Mods/H1PartMuon.h"

static H1PartJPsiArrayPtr jpsi;
// Base class: Stores the iterator
class JpsiBaseCut: public BaseCut {
  public:
    JpsiBaseCut (FillIterator& iter_) : iter(iter_) {};
  protected:
    FillIterator& iter;
};

// Selects only elastic J/psi candidates
class JpsiElasticCut: public JpsiBaseCut {
  public:
    JpsiElasticCut (FillIterator& iter_) : JpsiBaseCut(iter_) {};
    virtual bool operator() () const {
      return (iter() > -1) && (jpsi[iter()]->IsElastic() == kTRUE);
    }; 
};

// Selects only J/psi candidates decaying to 2 identified muons
class Jpsi2MuCut: public JpsiBaseCut {
  public:
    Jpsi2MuCut (FillIterator& iter_) : JpsiBaseCut(iter_) {};
    virtual bool operator() () const {
      return (iter() > -1) && 
             (jpsi[iter()]->GetTrack1()->GetParticle()->IsMuon()) &&
             (jpsi[iter()]->GetTrack2()->GetParticle()->IsMuon());
    }; 
};

But this code is still easy enough to be completely contained in a single header file, without the need for a .C file, and the resulting analysis code will look very clean:

  BaseCut&  jpsielastic    = *new JpsiElasticCut (mods_JPsi);
  BaseCut&  jpsi2mu        = *new Jpsi2MuCut (mods_JPsi);
  
  FloatFun& jpsimass       = mods_JPsi.GetMass();
  
  Binning massbinning (40, 2., 4.);
  
  // Mass histogram for elastic J/psi mesons decaying to 2 muons:
  SFH1F *hJpsiElasticTT   = new SFH1F ("jpsi", "J/psi->(#mu-#mu)", massbinning, this,
                                       jpsimass, 
                                       jpsielastic && jpsi2mu,
                                       0, 
                                       mods_JPsi);

ODS Access: Generic Bank Access

The data on H1 ODS contains the full DST information. Part of that data is available through special tracks and cluster classes, part is only available through access to objects that correspond to the original DST banks.

The SFH package provides means for a generic access to bank objects through classes defined in jbltools/sfh/h1/H1BankFuns.h.

Here is some example code:

#include "jbltools/sfh/h1/H1BankFuns.h"
DataLoop::DataLoop()
{
  // An object that represents the dtra (DST track) bank:
  JBLH1Bank& dtra = *new JBLH1Bank ("DTRA");
  // An iterator that loops over all DTRA tracks
  JBLH1BankIterator& dtra_it = dtra.iter();
  // A histogram that the pt of all DTRA tracks with 20<theta<160 deg:
  // (column 0 of the bank contains 1/pt, signed,
  //  column 2 contains the theta value):
  SFH *h = new SFH1F ("dtrapt", "DTRA track pt", 100, 0., 10., this, 
                      1/abs(dtra_it.GetFloat(0)),              // the track pt
                      20 < 57.2958*dtra_it.GetFloat(2) < 160,  // cut on theta
                      0,                                       // weight 1
                      dtra_it);                                // the track iterator
}  

Objects of type JBLH1Bank represent an H1 bank. Upon creation, they create an H1BankPtr object that points to the bank.

An JBLH1Bank object has a method iter() that returns an JBLH1BankIterator object, i.e. a special FillIterator, that can be used to loop over the rows of the bank.

An JBLH1BankIterator object has methods GetFloat(i), GetFloatFromInt(i), and GetInt(i) which create function objects that return the value of column i of the row selected by the iterator. GetFloat and GetFloatFromInt return FloatFun objects for columns that are float- or int-valued, respectively, and GetInt returns an IntFun object for an int-valued column.

Therefore, one could also write code like this:

  JBLH1Bank& dtra = *new JBLH1Bank ("DTRA");
  JBLH1BankIterator& dtra_it = dtra.iter();
  
  // Azimuthal angle phi
  FloatFun& dtraPhi   = dtra_it.GetFloat(1);
  // Track transverse momentum
  FloatFun& dtraPt    = 1./abs(dtra_it.GetFloat(0));
  // Link to forward track, 0 for central tracks
  IntFun&   dtraForw  = dtra_it.GetInt(14);  
  
  // Cut on theta:
  BaseCut& thetaCut = 20 < 57.2958*dtra_it.GetFloat(2) < 160;
  // Cut on central tracks
  BaseCut& centralCut = dtra_it.GetInt(14)==0;

Generated on Thu Oct 26 12:55:27 2006 for SFH by doxygen 1.3.2