StMcEvent |
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
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.
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
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:
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.
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.
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.
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; iPadrowThe 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.numberOfPadrows(); iPadrow++) { // Get the Padrow hit collection of the sector StTpcPadrowHitCollection* tpcPadRowHitColl = tpcSectHitColl->padrow(iPadrow); for (unsigned int iHit=0; iHit hits().size(); iHit++){ // get the hits in the padrow StMcTpcHit mcTpcHit = tpcPadRowHitColl->hits()[iHit]; // use the hit now...
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;
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;
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-20This 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.