The Event Record
The Event
class for event records basically is a vector of
Particle
s, so that it can expand to fit the event size.
The index operator is overloaded, so that event[i]
corresponds to the i
'th particle of an Event
object event
. Thus event[i].id()
returns the
identity of the i
'th particle. References to the first,
i
'th and last particle are obtained with
event.front()
, event.at(i)
and
event.back()
, respectively.
The event size can be found with size()
, i.e. valid
particles are stored in 0 <= i < event.size()
.
Line 0 is used to represent the event as a whole, with its total
four-momentum and invariant mass, but does not form part of the
event history. Lines 1 and 2 contains the two incoming beams, and
only from here on history tracing works as could be expected. That
way unassigned mother and daughter indices can be put 0 without
ambiguity. Depending on the task at hand, a loop may therefore start
at an index 1 without any loss. Specifically, for translation to other
event record formats such as HepMC [Dob01], where the first
index is 1, the Pythia entry 0 definitely ought to be skipped in order
to minimize the danger of errors.
New particles can be added to the end of the current event record
with append(Particle)
, or
append(id, status, mother1, mother2, daughter1, daughter2,
col, acol, p, m, scale)
where p
is the four-momentum vector, and everything except
id
defaults to 0. The append
method returns
the index of the new particle position.
The existing particle at index iCopy
can be copied to the end
with copy(iCopy, newStatus = 0)
. By default, i.e. with
newStatus = 0
, everything is copied precisely as it is,
which means that history information has to be modified further by hand
to make sense. With a positive newStatus
, the new copy is set
up to be the daughter of the old, with status code newStatus
,
and the status code of iCopy
is negated. With a negative
newStatus
, the new copy is instead set up to be the mother
of iCopy
.
A listing of the whole event is obtained with list()
. This
function takes an ostream
object as an optional argument.
The basic id, status, mother, daughter, colour, four-momentum
and mass data are always given, but the following switches can be
set to provide further information, or restrict the set of particles
listed:
flag name="Event:listFinalOnly" default="off"
The alternative mode, with this option on, omits all intermediate
particles, so that only ones with status > 0 are shown.
flag name="Event:listScaleAndVertex" default="off"
The alternative mode, with this option on, gives a second line
for each particle, with the production scale (in GeV), the
production vertex (in mm or mm/c) and the invariant lifetime
(also in mm/c).
flag name="Event:listMothersAndDaughters" default="off"
The alternative mode, with this option on, gives a list of all
daughters and mothers of a particle, as defined by the
motherList(i)
and daughterList(i)
methods
described below. It is purely intended for debug purposes,
e.g. when writing an interface to another event record format.
flag name="Event:extraBlankLine" default="off"
With this option on, an extra blank line is inserted after each
particle. There is a tradeoff between improved legibility, in
particular for Event:listMothersAndDaughters
on, and a
longer listing.
flag name="Event:listJunctions" default="off"
With this option on, a list of all junctions in the event is
displayed after the normal particle list.
These choices are stored at the initialization stage of the event.
If you want to change values later, you have to execcute an
Event::initStatic()
yourself for them to take effect.
The event record can be emptied for the next event by a
clear()
. The last n
entries can be removed by
popBack(n)
, where n = 1
by default.
The user would normally be concerned with the Event
object
that is a public member event
of the Pythia
class.
Thus, having declared a Pythia
object pythia
,
pythia.event[i].id()
would be used to return the identity
of the i
'th particle, and pythia.event.size()
to
give the size of the event record.
A Pythia
object contains a second event record for the
hard process alone, called process
, used as input for the
generation of the complete event. Thus one may e.g. call either
pythia.process.list()
or pythia.event.list()
.
To distinguish those two rapidly at visual inspection, the
"Pythia Event Listing"
header is printed out differently,
in one case adding "(hard process)"
and in the other
"(complete event)"
. This is set by a header(string) method.
One data member in an Event
object is used to keep track of the
largest col()
or acol()
tag set so far, so that
new ones do not clash. The lastcolTag()
method returns the
last tag assigned, i.e. largest value in the current event, and
nextColTag()
ups it by one before returing the value. The
latter method thus is used when a new colour tag is needed.
mode name="Event:startColTag" default="100" min="0" max="1000"
This sets the initial value used, so that the first one assigned is
startColTag+1
, etc. The Les Houches accord [Boo01]
suggests this number to be 500, but 100 works equally well.
The scale()
methods can be used to set or get the scale
(in GeV) of the event as a whole. Further methods for event properties
may be added in the future.
There are also a few methods with an individual particle index
i
as input, but requiring some search operations in
the event record, and therefore not possible to define inside the
Particle
class:
method name="motherList(i)"
returns a vector<int>
containing a list of all the
mothers of a particle. This list is empty for entry 0 , while
normally it contains one, two or many mothers. The latter case
applies e.g. to string fragmentation, where the whole fragmenting
system is counted as mothers. Mothers are listed in ascending order.
method name="daughterList(i)"
returns a vector<int>
containing a list of all the
daughters of a particle. This list is empty for a particle that did
not decay (or, if the evolution is stopped early enough, a parton
that did not branch), while otherwise it can contain a list of
varying length, from one to many. Many partons may have the same
daughterList
, e.g. in the hard process and fragmentation steps.
For the two incoming beam particles, all shower initiators and beam
remnants are counted as daughters, with the one in slot 0 being
the one leading up to the hardest interaction.
method name="iTopCopy(i), iBotCopy(i)"
are used to trace carbon copies of the particle at index i
up
to its top mother or down to its bottom daughter. If there are no such
carbon copies, i
itself will be returned.
method name="iTopCopyId(i), iBotCopyId(i)"
also trace top mother and bottom daughter, but do not require carbon
copies, only that one can find an unbroken chain, of mothers or daughters,
with the same flavour id
code. The behaviour when trying to
trace a gluon through a shower, with its g -> g g branchings,
is then rather unpredictable. Similarly, a hard scattering such as
u u -> u u is better avoided. It should work well for "rare"
particles, not found in the beams, so that the program is not fooled
by ambiguities.
method name="sisterList(i)"
returns a vector<int>
containing a list of all the
sisters of a particle, i.e. all the daughters of the first mother,
except the particle itself.
method name="sisterListTopBot(i)"
returns a vector<int>
containing a list of all the
sisters of a particle, tracking up and back down through carbon copies
if required. That is, the particle is first traced up with
iTopCopy()
before its mother is found, and then all
the particles in the daughterList()
of this mother are
traced down with iBotCopy()
, omitting the original
particle itself. Any non-final particles are removed from the list.
Should this make the list empty the search criterion is widened so that
all final daughters are allowed, not only carbon-copy ones. A second
argument false
inhibits the second step, and increases
the risk that an empty list is returned. A typical example of this
is for ISR cascades, e.g. e -> e gamma where the photon
may not have any obvious sister in the final state if the bottom copy
of the photon is an electron that annihilates and thus is not part of
the final state.
method name="isAncestor(i, iAncestor)"
traces the particle i
upwards through mother, grandmother,
and so on, until either iAncestor
is found or the top of
the record is reached. Normally one unique mother is required,
as is the case e.g. in decay chains or in parton showers, so that
e.g. the tracing through a hard scattering would not work. For
hadronization, currently first-rank hadrons are identified with the
respective string endpoint quark, which may be useful e.g. for b
physics. However, currently ministrings or junction topologies give
false
. (??)
The Junction Class
The event record also contains a vector of junctions, which often
is empty or else contains only a very few per event. Methods are
available to add further junctions or query the current junction list.
This is only for the expert user, however, and is not discussed
further here, but only the main points.
A junction stores the properites associated with a baryon number that
is fully resolved, i.e. where three different colour indices are
involved. There are two main applications,
- baryon beams, where at least two valence quarks are kicked out,
and so the motion of the baryon number is notrivial;
- baryon-number violating processes, e.g. in SUSY with broken
R-parity.
Information on junctions is set, partly in the process generation,
partly in the beam remnants machinery, and used by the fragmentation
routines, but the normal user does not have to know the details.
For each junction, information is stored on the kind of junction, and
on the three (anti)colour indices that are involved in the junction.
The possibilities foreseen are:
kind = 1
: incoming colourless particle to three
outgoing colours (e.g. baryon beam remnant or
neutralino -> q q q
);
kind = 2
: incoming colourless particle to three
outgoing anticolours;
kind = 3
: one incoming anticolor (stored first)
and two outgoing colours (e.g. antisquark decaying to quark);
kind = 4
: one incoming color (stored first) and two
outgoing anticolours;
kind = 5
: incoming colour octet to three colours,
where the incoming colour passes through unchanged and so need not
be bokkept here, while the incoming anticolor (stored first) and the
two outgoing colours are (e.g. gluino decay to three quarks);
kind = 6
: incoming colour octet to three anticolours,
where the incoming anticolour passes through unchanged and so need not
be bookkept here, while the incoming color (stored first) and the two
outgoing colours are.
The odd (even) kind
codes corresponds to a +1 (-1) change in
baryon number across the junction.
Warning:Currently only kind = 1, 2
are
implemented.
The kind and colour information in the list of junctions can be set
or read with methods of the Event
class, but are not of
common interest and so not described here.