#define MAXTRACKS 20
//								      |
//	Fragment of code to book and fill a Column-wise Ntuple        |
//								      |
#include <string>
#include "HepTuple/HepHBookFileManager.h"
#include "HepTuple/HepNtuple.h"
#include "ZMutility/FixedTypes.h"
#include <cstdlib>
#include <iostream.h>
#include <cmath>
#include <vector>

//  Declare the pointer to the file manager at this level to
//  make it available at file scope.

HepFileManager *tManager;

Int4 main(Int4 argc, char ** argv)
  Int4 nevents=2000;
  void generate( Int4, bool );

//  Initialize HBOOK and open an RZ file.  Note that this is now the only
//  direct invocation of an HBOOK-specific method. Using it here triggers
//  everything else even though all subsequent references below are to
//  generic things like HepHistogram.

//  Note that the top directory on the RZ file will have the same name as
//  the file itself.  There's no choice in this but it isn't a big deal
//  since the name of the top directory isn't actually recorded anywhere.

  tManager = new HepHBookFileManager("toyz.rz");

//  Book and fill an ntuple in a function named generate.

  delete tManager;
  return 0;

void generate(Int4 nevents, bool first)

//  Instantiate an ntuple, declare it to be columnwise (this is default
//  anyhow) and tell the manager where to find the data items when we tell
//  it to capture. This is a handy way to do this.  We establish a reference
//  to the data item here and give the item a value when the program logic
//  warrants it. After all items have been assigned a value, we tell the
//  ntuple machinery to capture everything. This works because the location
//  of the data doesn't change - just the value sitting in that location.

  HepNtuple & tupl = tManager->ntuple("Toy CWNtuple")


//  N. B. In addition to defining the ntuple block names and column names,
//        these declaration also indirectly declare the data types of the
//        corresponding items, either through the type of the data item,
//        the type of the default value or the type of the referenced item.

//  Define a block named TRACKS and a column named Ntracks.  In addition,
//  declare this column to contain an index variable and specify it's range.

  cout << "\nDeclaring columns, ranges and index variables." << endl;
  tupl.span("TRACKS::Ntracks",0,MAXTRACKS);	    // specify full nametag

//  Declare a column array named Pt and say that it is a variable length
//  array indexed by Ntracks and has maximum dimension MAXTRACKS.  Repeat
//  this for each column within the Tracks block. Note that we specifically
//  cast the default value as a Float8.  This fixes the type of the data.

//  There are a number of variations on how to declare indexed column arrays.
//  We use several of them here to demonstrate some of the possibilities.

  tupl.columnArray("TRACKS::Pt",  1,(Float8)99.9);
  tupl.dimension("TRACKS::Pt",MAXTRACKS);	// specify nametag

  tupl.columnArray("TRACKS::Eta", 1,(Float8)99.9);
  tupl.dimension(MAXTRACKS);			// default nametag to "current"

  tupl.columnArray("TRACKS::Phi", 1,(Float8)99.9);
  tupl.index("TRACKS::Phi","Ntracks");		// specify nametag

  tupl.columnArray("TRACKS::Px",  1,(Float8)99.9);
  tupl.index("Ntracks");			// default nametag to "current"

// Two-fold method cascade since each returns another reference

  tupl.columnArray("TRACKS::Py",  1,(Float8)99.9).dimension(MAXTRACKS);

// Three-fold method cascade since each returns another reference

  tupl.columnArray("TRACKS::Pz",  1,(Float8)99.9).dimension(MAXTRACKS).index("Ntracks");

//  Finally, print out the block descriptor string that this produced.

  cout << "\nPrint the chForm string for Block TRACKS to see what we got." ^lt;< endl;
  cout << tupl.blockFormat("TRACKS") << endl;

//  Release everything so we can define values for all quantities.

  cout << "\nClear all data in preparation for presenting values." << endl;
//  Do whatever is needed to define numTracks and fill the arrays it indexes.

//  Capture a bunch of ntuple entries before they go out of scope, store
//  everything and clean up for the next event.

    tupl.capture("TRACKS::Pt" ,&(PtArray[0]));
    tupl.capture("TRACKS::Px", &(PxArray[0]));
    tupl.capture("TRACKS::Py", &(PyArray[0]));
    tupl.capture("TRACKS::Pz", &(PzArray[0]));