StMcEvent

STAR Monte Carlo Data Model

New Version

The new version of StMcEvent is ready for testing. A full description will be given in the User Guide. The new User's Guide & Reference Manual is now ready too. Gene made a nice page where the PS documentation can be obtained. Click here to get to Gene's page. In the meantime, a description of the main changes in StMcEvent will be given below. The aim is that it will help people get started while the more complete documentation is done. For quick reference, look at the brief class description below. This lists the most commonly used methods of the StMcEvent, StMcTrack, StMcVertex and StMcHit classes.

The Particle Table is now in! Check out some conventions that you have to look out for to use it properly in the Particle Table section

Description

StMcEvent is a package that compliments the use of StEvent, STAR's Data Model. The aim of this package is for the user to be able to access and analyze Monte Carlo with the same object oriented approach as StEvent . The top class is an instance of StMcEvent, and a pointer to this class enables access to all the relevant Monte Carlo information. When running through a typical STAR analysis chain, like the one in bfcread.C, a Maker does the actual filling of the StMcEvent objects. In this case, it is StMcEventMaker. This Maker then has a member function to give to the other makers down the chain access to the instance of StMcEvent. Through this pointer, one can then navigate through the tracks, vertices and hits in the event. The User's Guide is now outdated. The previous version contained a list of all the member functions of the previous StMcEvent class and all classes in the package. The new version has a different structure, and more classes. A good place to look in the meantime is the StEvent User's Guide, since StMcEvent follows the basic structure of StEvent. The classes, of course, are different, but most of the methods have the same names, and similar classes have similar names. For example, the basic class out of which all tracks in StEvent are made out of, is StTrack. In StMcEvent, all tracks are of type StMcTrack. The difference is that StEvent has many kinds of tracks: StGlobalTrack, StPrimaryTrack while StMcEvent only has StMcTrack.

The information contained in StMcEvent is designed to be simply a reflection of the information already available in the existing g2t tables. The primary keys and foreign keys are replaced by associations between classes through pointers.


Getting Started

Currently, StMcEvent compiles and runs in Linux, Solaris and HP. To use it, there is a macro available under CVS: $STAR/StRoot/macros/examples/StMcEventReadMacro.C

This macro will read a geant.root file (created using the bfc.C macro) and will load the StMcEvent objects from the tables found in that file. Note that it does not do any analysis or histogramming at all. This step would be done later by the user once StMcEvent is loaded.

However, a quick check to see if everything is in place can be made simply by running the macro on a particular file. (The current default is /afs/rhic.bnl.gov/star/data/samples/*.geant.root)

root4star[0] .x StMcEventReadMacro.C(1,"myfile.geant.root")

The first argument in this invocation is the number of events to process, and the second argument is the file name. A successful run ensures that a) the file is there, b) it contains the GEANT information, and c) you are able to run the packages in your environment. You can then start thinking about what to do with the GEANT information.

However, looking at the Monte Carlo Data by itself doesn't provide the most fruitful possibility for analysis. That is why the main goal of StMcEvent is to be used in conjunction to StEvent to analyze reconstructed and Monte Carlo data together. This is done using StAssociationMaker. This package has its own documentation.

One thing to keep in mind when using StAssociationMaker or any code that uses StEvent is that these packages RELY ON THE NEW DST TABLES. This means that to use them you have to make sure that the *.dst.root file you want to use can actually be read by StEvent. Moreover, most of the new dst files are NOT produced with their *.geant.root file. So before running StAssociationMaker, make sure that


Conventions and use of Tracks from Particle Table

Originally, there was no particle table. All tracks were obtained from the g2t_track table. The flag "event generator label" from the g2t_track table gives you the index from the particle table where this particular track is found. If this variable is zero, that means that the track is completely a geant track, and does not come from the event generator. All tracks, in addition, have a primary key. Each track also knows about its start and stop vertex, and those vertices in turn know about its parent and daughter tracks, so you could navigate forth and back in this way, going through the vertices.

Now, enter the particle table. First of all, there is no such thing as the corresponding vertex table for this. All there is supposed to be in the table in terms of mother-daughter relationships is:

When I looked at some hijing events, I saw that the daughter indices were ALWAYS ZERO. No information was contained there. So at the moment I just don't use this (but this is something to take up with the simulations leader...) So all the information available there was the mother indices. In addition, the event generator ID's are kept according to the PDG standard.

Now, the track entries in StMcEvent is done in the following way:

First of all, I fill all entries from the particle table. All entries up to this point will then have:

If they have a parent (according to the "motherIndex" from particle.idmohep[0]) we enter it.

Notice that the event generator will probably have additional interactions, not necessarily only decays, that will give a parentage relationship EVEN IF ALL DECAYS ARE TURNED OFF. Hijing for example, starts from the parton level, and the bookkeeping of the parton interactions will yield as a result entries in the particle table which have a parent() != 0.

After we fill from the particle table (and you already see that there will be some tracks that have parent!=0 at this level at least for some event generators) we fill the StMcEvent tracks from the g2t_track table. This is done in the same way as before the particle table came into the game. These tracks will then ALL have:

Now here's the tricky part. The tracks that come directly from the event generator will ALSO have "event generator label" > 0. That's how we know where to find them in the particle table. So this track should already have been entered into StMcEvent. To avoid overcounting, I merge the information of both tables into a single StMcTrack. These entries will then have

And if the relevant entry in the particle table has a parent (and I already said why this may be so even if decays are turned off) then we assign it to this track appropriately. Maybe you're getting confused because as far as GEANT is concerned, these tracks don't have a parent. But remember that now were crossing the boundaries of GEANT, and we're also looking in the particle table, and a track that in GEANT will have no parent, most probably will have one in the particle table. That is why I would NOT recommend checking whether parent() == 0 to determine if a track is primary. Actually, if it IS zero, I would expect it to be one of the initial partons, and most certainly these will not have any associated tracks because they only live in the event generator.

Now for all g2t_tracks, including those that came from the particle table, we know its parent vertex from the g2t_vertex table. Then a relationship between them is established. This is what determines which tracks come from the primary vertex and which ones don't.

There is even a data member from the g2t_event table that specifies the number of primary tracks (at the table level). In one of the checks I always make when debugging is that this number should equal

	mcEvent->primaryVertex()->daughters().size()
	

There shouldn't be any discrepancy when things are fine. If there is a discrepancy, then this signals that something is amiss.

So the easiest way to get the primary tracks from StMcEvent is:

	mcEvent->primaryVertex()->daughters()
	

This should be it! But just to check what we're doing, check when you loop over them if they have:

If one is looking for a particle that was decayed in the event generator and its products then passed to GEANT, then the only modification to the above procedure is to ask for the parent of the relevant primary particles we are interested in. For example, if a phi is decayed into an e+e- pair, then we check whether the primary track is an electron and if so, look at its parent. If it is a phi, we're done.


Brief Class Description

StMcEvent

The top class is StMcEvent, and through it, all other objects like tracks and hits are accessed. The information stored in the g2t_event table is also stored here:
  
    unsigned long                eventGeneratorEventLabel() const;
    unsigned long                eventNumber() const;
    unsigned long                runNumber() const;              
    unsigned long                type() const;
    unsigned long                zWest() const;
    unsigned long                nWest() const;
    unsigned long                zEast() const;
    unsigned long                nEast() const;
    unsigned long                numberOfPrimaryTracks() const;
    float                        impactParameter() const;
    float                        phiReactionPlane() const;
    float                        triggerTimeOffset() const;
    

The other objects are accessed through the member functions:

    StMcVertex*                    primaryVertex();
    StSPtrVecMcVertex&             vertices();
    StSPtrVecMcTrack&              tracks();
    StMcTpcHitCollection*          tpcHitCollection();
    StMcSvtHitCollection*          svtHitCollection();
    StMcFtpcHitCollection*         ftpcHitCollection();
    
These methods also have a const version, in case these are needed.

Flat Arrays

The naming convention follows that of StEvent. However, the underlying arrays in StEvent are persistent, and in StMcEvent these are really transient STL vectors. The names mean roughly the following. StPtrVecMcVertex is a VECtor of PoinTeRs to objects of type StMcVertex. StSPtrVecMcVertex is a Structural VECtor of PoinTeRs to objects of type StMcVertex. The difference is in terms of ownership. The "Structural" array owns the objects it points to, and it is responsible for deleting the objects when the object itself gets deleted. The other one does not own the objects it points to and is just responsible for deleting itself. This makes it easier for the developers to know who owns what to make sure that SOMEONE deletes the objects and that they DON'T get deleted twice.

The tracks and vertices in StMcEvent are stored in a flat array. There is a difference with StEvent in that there is no need for Track Nodes, Global or Primary Tracks. StMcEvent only has StMcTracks.

Hit Collections

The HitCollections, are now classes in themselves, hits are not stored in flat arrays like before. The idea is now to store the hits in an ordered manner, according to sub detector structure. This is done in the follwing way:

StMcTpcHitCollection -> StMcTpcSectorHitCollection -> StMcTpcPadrowHitCollection -> Hits

StMcSvtHitCollection -> StMcSvtLayerHitCollection -> StMcSvtLadderHitCollection -> StMcSvtWaferHitCollection -> Hits

StMcFtpcHitCollection -> StMcFtpcPlaneHitCollection -> Hits

The FTPC Hit collection structure is different than StEvent because the Monte Carlo hits don't know about FTPC Sectors. These are determined by the reconstruction based on the magnetic field, ExB distortions etc.

Here's example loop to get to the TPC Hits. The loops for the SVT and FTPC will have the same structure, replacing a TPC "sector" with an SVT "layer" or an FTPC "plane", etc. as in the structure above.

StMcTpcHitCollection* mcTpcHitColl = mcEvent->tpcHitCollection();
  for (unsigned int iSector=0;
       iSector < mcTpcHitColl->numberOfSectors(); iSector++) {

    // Get the sector hit collection

    StTpcSectorHitCollection* tpcSectHitColl = rcTpcHitColl->sector(iSector);

      for (unsigned int iPadrow=0;
           iPadrownumberOfPadrows(); iPadrow++) {

	// Get the Padrow hit collection of the sector 

	StTpcPadrowHitCollection* tpcPadRowHitColl = tpcSectHitColl->padrow(iPadrow);

	for (unsigned int iHit=0;
	     iHithits().size(); iHit++){

	  // get the hits in the padrow

	  StMcTpcHit mcTpcHit = tpcPadRowHitColl->hits()[iHit];

	  // use the hit now...
	    
      

The names of the methods are similar to those in StEvent, only the classes are named differently. Also note that the numbering scheme, as requested by the SVT group, has the hits returning a layer, ladder, wafer (SVT), sector, padrow (TPC) and plane (FTPC) starting from 1. So if you use these methods along with arrays, make sure to subtract 1. This is also discussed in the StEvent manual.

StMcTrack

Here is a list of the methods most commonly used for StMcTrack. The "set" methods, constructors, and other operators are not shown here. An StMcTrack has knowledge of its four-momentum (and functions derived from this), the hits that form a part of this track and the type of particle that produced the track.
    const StLorentzVectorF&      fourMomentum() const;
    const StThreeVectorF&        momentum() const; 
    float                        energy() const; 
    float                        pt() const; 
    float                        rapidity() const; 
    float                        pseudoRapidity() const; 
    StMcVertex*                  startVertex(); 
    StMcVertex*                  stopVertex(); 
    StPtrVecMcVertex&            intermediateVertices();
    StPtrVecMcTpcHit&            tpcHits(); 
    StPtrVecMcSvtHit&            svtHits(); 
    StPtrVecMcFtpcHit&           ftpcHits(); 
    StParticleDefinition*        particleDefinition(); 
    int                          isShower() const; // 1 = yes, 0 = no
    long                         geantId() const;
    

StMcVertex

The vertices in StMcEvent know their position, geant volume, time of flight, geant process that produced them and, more importantly, the daughter tracks and parent track.
    const StThreeVectorF&       position() const;
    StPtrVecMcTrack&            daughters();
    unsigned int                numberOfDaughters();
    StMcTrack*                  daughter(unsigned int);
    const StMcTrack*            parent();
    string                      geantVolume() const;
    float                       tof() const;
    long                        geantProcess() const;
    

StMcHit

All hit classes inherit from StMcHit, which provides the following methods:
    const StThreeVectorF& position() const;
    float                       dE() const; // energy loss
    float                       dS() const; // path length within padrow
    StMcTrack*         parentTrack() const;
    

In addition, the derived hit classes know which subdetector they belong to:

StMcTpcHit

    unsigned long sector() const; // 1-24
    unsigned long padrow() const; // 1-45
    

StMcSvtHit

    unsigned long layer()  const; // layer=[1-6]
    unsigned long ladder() const; // ladder=[1-8]
    unsigned long wafer()  const; // wafer=[1-7]
    unsigned long barrel() const; // barrel=[1-3]
    

StMcFtpcHit

    unsigned long plane()  const; // 1-20
    
This covers the basic classes and the methods that will most frequently be needed to use StMcEvent. The header files are nevertheless the definitive and more complete source, and these can be accessed from the software guide this file is found in, under the "src" link for StMcEvent.
StMcEvent is a work in progress. For questions, contact
Manuel Calderon de la Barca Sanchez
or
Michael A. Lisa
Last modified: Tue Apr 18 18:50:26 EDT 2000