The HepPDT Particle Data Table classes

This is a suggestion for a common interface to particle properties to be included in CLHEP. If you have comments or suggestions please send them to the LHC++ discussion list cern-lhcxx@listbox.cern.ch. If you want to try it out you should download the file CLHEP-PDT.tar.gz and unpack it in a CLHEP source directory and modify the configure script and Makefile to also handle the new PDT subdirectory.

The general idea is to separate the notions of particle properties and particle instances. The classes presented here should be able to handle most of the particle properties as given by the Particle Data Group, but should be independent of any particular implementation of particle instances. It should however be able to handle user-defined information relevant for a particular particle instantiation scheme.

The main class in this package is the HepPDTable class. It maintains a set of HepParticleData objects, one for each type of particle, containing the properties of this particle type (note that there is no hierarchy of particle data classes - all particle types are represented by an object of the HepParticleData class. The objects are stored in an std::map indexed with the STDHEP id number of each particle. (Maybe a hash table would allow for slightly faster retrieval, but I doubt it would make much difference.) A pointer to a HepParticleData object can be retrieved by giving the corresponding STDHEP id number, or by giving a name in a character string. The HepPDTable also maintains a user defined translation table mapping the STDHEP id numbers to any numbering scheme.

The HepPDTable class also maintains a set of HepParticleMatcher objects. Each of these HepParticleMatcher objects represent a group of particles types such as charged mesons or heavy quarkonium and are used in decay tables to represent inclusive decay modes such as B -> D + anything. The matchers are a hierarchy of of classes where the HepParticleMatcher is a base class implementing a std::set of pointers to particles matched by the corresponding object, while the method for determining whether a given HepParticleData object is matched is implemented in derived classes. The matchers are stored in an std::map indexed by a character string name. If all the matched particles have some common properties, the HepParticleMatcher objects will also have these properties accessible with methods corresponding to those in the HepParticleData class.

A HepParticleData object contains, besides the STDHEP number and name, a mass, a width, and a decay length, all with errors, a color, a spin, a charge, a flag to tell whether it is stable, a pointer to its anti-partner a decay table and a set of producer objects. A producer object can be assigned by a user and should typically be able to produce an instance of a particle of the type represented by the current HepParticleData object and may also contain additional data needed for for the instantiation. The only requirement on this producer object is that it should be derived from the (empty) abstract base class HepParticleProducer. Since it is conceivable that different classes of particle instances could be used in the same run, the HepParticleData object actually contains an std::map of (pointers to) producer objects indexed by a package number, where a package could be Geant 4 or Babar or what not. The package number is assigned by the HepPDTable when handed a package handler object derived from the base class HepPackageHandler, which is the class handling the interaction between user-defined packages and the particle data table.

The decay table is implemented in the class HepDecayTable and is a list of HepDecayMode objects. Each HepDecayMode object contains an stl::multiset of pointers to HepParticleData objects corresponding to specified decay products. It also contains a stl::multiset of pointers to HepParticleMatcher objects, where each matcher corresponds to one decay product of the set matched by this matcher. In addition the HepDecayMode object contains a pointer to a HepParticleMatcher object corresponding to any number of decay products of the matching set. In this way one can represent decay modes as complex as 'B+ -> any D meson pi+ pi- any number of other mesons'. A HepDecayMode object also contains a set of decay modes for specifying subsequent resonant decays and a set of HepParticleData objects corresponding to excluded intermediate resonance. Hence the following three decay modes can be made distinct:

Each decay mode has a character string tag to enable identification. The syntax is the name of the decaying particle followed by a colon followed by a comma separated list of decay product specifiers and ended by a semicolon. The decay products specifiers can either be the name of a specified decay product, the tag of a decay mode specifying resonant decays enclosed in square brackets, the name of a particle matcher object preceded by a '?'corresponding to one decay product, the name of a particle matcher object preceded by a '*' corresponding to an unknown number of decay products, or the name of an excluded resonance preceded by '!'. The order is important: first any number of specified decay products ordered in increasing STDHEP numbers, then any number of subsequent resonant decays ordered in lexicographical order of the tags, followed by any number of (one-to-one) matchers also in lexicographical order, one or none wildcard (one-to many) matcher, and, finally, any number of excluded resonances again in lexicographical order. For example the first decay above will have the tag "B+:pi-,pi+,?AnyDMeson,*AnyMeson;" and the three subsequent examples "D+:K-,e+,nu_e,pi+;", "D+:e+,nu_e,[K*~0:K-,pi+;];" and "D+:K-,e+,nu_e,pi+,!K*~0;". Each decay mode has a list of pointers to overlapping decay modes, hence the first of the three last modes would have pointers to the last two.

Each decay mode contains a branching ratio corresponding to the measured number with errors given by the particle data group. It is clear that the above scheme will not be able to cope with all the different flavours of presenting decay mode used by the Particle Data Group, but it may come pretty close.

A HepDecayMode object also keeps an std::map of (pointers to) HepDecayModel objects paired with a branching ratio indexed by a package number. the HepDecayModel object should typically be able to perform the actual decay for the particle instantiation scheme used in the corresponding package, and may also contain additional data needed for the decay. For each package the HepDecayTable for a given particle maintain a list of the decay modes with non-zero branching ratios assigned for this package, and has a method for quickly retrieving one of these based on a given a random number. The HepDecayTable does not however check whether there are any overlaps among the decay modes.

The user interface is typically handled through the HepPDT class. The HepPDTable class does not have any public constructors and only one such object is created and maintained by the completely static HepPDT class. It would of course be possible to have the HepPDTable class itself fully static, but it would then be impossible to differentiate between methods which modifies the data table and which do not since static methods cannot be declared const. Instead the HepPDT class implements directly static versions of all const methods of the the HepPDTable class, while all non-const methods are only accessible indirectly via the theTable() method returning a reference to the HepPDTable object.

None of the classes here are persistent and the only way of saving data between runs is with a ASCII file. All information is, however, stored in STL containers, so once Objectivity starts supporting them, it may not be impossible to make these classes persistent.

PS. In case you wonder about the html version of the header files linked into this document, I made them by hacking around a bit in classdoc. Looks rather neat, considering the tiny amount of work I put into it.