Advanced Usage
 
  - The subsystems
- The beams
On this page we collect information on a number of classes that 
the normal user would not encounter. There are cases where the 
information is essential, however, for instance to 
implement your own showers.The subsystems
 
 
One aspect that complicates administration is that an event 
can contain several subsystems, each consisting of either 1) one MPI 
and its associated ISR and FSR or 2) one decaying resonance and its 
associated FSR. To first approximation these systems are 
assumed to evolve independently, but to second they are connected by 
the interleaved evolution, and potentially by colour-reconnection or 
rescattering effects. 
The partons of a given subsystem therefore do not have to be stored 
consecutively. 
 
 
The PartonSystems class is primarily used to keep track 
of the current positions of all partons belonging to each system, 
represented by the index iPos for a parton stored in the 
event-record slot event[iPos]. With "all" we mean the 
current set of outgoing partons, as well as the currently defined two 
incoming partons that system (for 2→n processes) or 
one incoming parton in the case of a decay (1→n) process. No 
intermediate-state (off-shell) ISR or FSR 
partons are present. That is, the parton system stores all partons 
that could be subject to some action in the next step of the 
combined MPI/ISR/FSR/BR description. As a special case, an outgoing 
parton is stored even if it undergoes a rescattering, and thus no 
longer belongs to the final state proper. 
 
 
Note also that an unstable (decaying) resonance will normally appear 
in two different systems; once, as an outgoing parton in the system 
that produced it (a hard process or the decay system of a previous 
resonance decay), and once as an incoming parton in its own decay system. 
 
 
The partonSystems instance of PartonSystems 
class is a public member of the Pythia top-level class, 
but is also available as a pointer partonSystemsPtr in 
various PartonLevel classes, e.g. inside the current 
instances of the TimeShower and SpaceShower 
classes. 
 
 
A number of PartonSystems methods can be used to set or 
get information on the subsystems: 
 
- clear()resets all the contents in preparation for the 
next event.
- addSys()add a new (initially empty) subsystem to the 
current list and return its index- iSysin the list, 
where index 0 is the hardest subcollision and so on.
- sizeSys()the number of separate subsystems.
- setInA(iSys, iPos), setInB(iSys, iPos)store position- iPosof the incoming parton from beam A or beam B to the- iSys'th subcollision. These values are 0 initially, and 
should so remain if there are no beams, such as in resonance decays.
- setInRes(iSys, iPos)stores position- iPosof the incoming (decaying) resonance whose 
decay produced the outgoing partons for the- iSys'th 
system. This value is 0 initially and should so remain for systems 
that are not produced by the decay of a resonance, such as 
2→n subcollision systems.
- addOut(iSys, iPos)store position- iPosof a new outgoing parton in the- iSys'th subcollision, 
by appending it at the end of the current vector, with beginning in 
slot 0.
- setOut(iSys, iMem, iPos)store position- iPosin the- iMem'th slot in the vector of outgoing partons in the- iSys'th subcollision. Here- iMemmust be in 
the range already constructed by- addOutcalls.
- replace(iSys, iPosOld, iPosNew)replace the existing 
incoming or outgoing parton position- iPosOldby- iPosNewin the- iSys'th subcollision.
- setSHat(iSys, sHat)set the invariant squared mass- sHatof the- iSys'th subcollision.
- hasInAB(iSys)true if an incoming parton has been set 
for beam A or beam B (and hence should have been set for both) in the- iSys'th subcollision, else false.
- getInA(iSys), getInB(iSys)the position- iPosof the incoming parton from beam A or beam B to the- iSys'th 
subcollision.
- hasInRes(iSys)true if an incoming (decaying) 
resonance has been set for the- iSys'th parton system, 
else false.
- sizeOut(iSys)the number of outgoing partons 
in the- iSys'th subcollision.
- getOut(iSys, iMem)the position- iPosof an outgoing parton in the- iSys'th subcollision, 
with the- iMemrange limited by- sizeOut(iSys). 
These partons are not guaranteed to appear in any particular order.
- sizeAll(iSys)the total number of incoming and outgoing 
partons in the- iSys'th subcollision.
- getAll(iSys, iMem)the position- iPosof an incoming or outgoing parton in the- iSys'th subcollision. 
In case there are beams it gives same as- getInA(iSys) and-  getInB(iSys)for indices 0 and 1, and thereafter agrees with- getOut(iSys, iMem)offset two positions. In case there is 
an incoming (decaying) resonance set for the system, it gives the same 
as- getInRes(iSys)for index 0, and thereafter agrees with- getOut(iSys, iMem)offset one position. If there are 
neither beams nor an incoming resonance set for the system, 
it is identical with- getOut(iSys, iMem).
- getSystemOf(iPos, alsoIn)returns the system 
(- iSys) of the parton specified by- iPos. 
If the parton is outgoing in one system and incoming in another (eg a 
decaying resonance), the system in which it is incoming will be returned if- alsoIn == true, else the system in which it is outgoing 
will be returned. The default is- alsoIn = false.
- getSHat(iSys)the invariant squared mass- sHatof the- iSys'th subcollision.
- list()print a listing of all the system information, 
except for the- sHatvalues.
New systems are created from the hard process, from resonance decays, and 
by the MPI, not from  any of the other components. Both FSR and ISR 
modify the position of partons, however. Since an FSR or ISR branching 
typically implies a new state with one more parton than before, an 
outgoing parton must be added to the system. Furthermore, in a 
branching, several existing partons may also be moved to new slots, 
including the incoming beam ones. 
In a FSR 1 → 2 branching it is irrelevant which parton position 
you let overwrite the existing slot and which is added to the end of 
the system. 
 
 
The system information must be kept up-to-date. Both the MPI, ISR, FSR and 
BR descriptions make extensive use of the existing information. As an 
example, the introduction of primordial kT in the beam remnants 
will fail if the information on which final-state partons belong to which 
system is out-of-date. The introduction of rescattering as part of the 
MPI framework adds further complications, where an outgoing parton of one 
subsystem may be the incoming one of another system. This part of the code 
is still under development. 
 
 
Currently the system information is kept throughout the continued 
history of the event. Specifically, resonance decays create new systems, 
appended to the existing ones. This could be useful during the 
hadronization stage, to collect the partons that belong to a resonance 
with preserved mass when a small string collapses to one particle, 
but is not yet used for that.The beams
 
 
The different subsystems are tied together by them sharing the same 
initial beam particles, and thereby being restricted by energy-momentum 
and flavour conservation issues. The information stored in the two 
beam particles, here called beamA and beamB, 
is therefore as crucial to keep correct as the above subsystem list. 
 
 
Both beam objects are of the BeamParticle class. 
Each such object contains a vector with the partons extracted from it. 
The number of such partons, beamX.size() (X = A or B), 
of course is the same as the above number of subsystems in the event 
record. (The two diverge at the BR step, where further beam remnants 
are added to the beams without corresponding to new subsystems.) 
The individual partons are accessed by an overloaded indexing 
operator to a vector of ResolvedParton objects. The 
iPos() property corresponds to the iPos 
one above, i.e. providing the position in the main event record of 
a parton. In particular, 
beamA[iSys].iPos() = partonSystemsPtr->getInA(iSys) and 
beamB[iSys].iPos() = partonSystemsPtr->getInB(iSys). 
Whereas thus the indices of the two incoming partons to a subsystem 
are stored in two places, the ones of the outgoing partons only 
appear in the system part of the PartonSystems class. 
 
 
Just as the subsystems in PartonSystems must be updated, 
so must the information in the two BeamParticle's, e.g. 
with methodsbeamX[iSys].iPos( iPosIn) when an incoming 
parton is replaced by a new one in line iPosIn. Furthermore 
the new parton identity should be set by beamX[iSys].id( idIn) 
and the new x energy-momentum fraction by 
beamX[iSys].x( xIn). The three can be combined in one go 
by beamX[iSys].update( iPosIn, idIn, xIn). 
 
 
To be specific, it is assumed that, at each step, the two incoming 
partons are moving along the +-z axis and are massless. 
Since the event is constructed in the c.m. frame of the incoming 
beams this implies that x = 2 E / E_cm. 
If the x values are not defined accordingly or not kept 
up-to-date the BR treatment will not conserve energy-momentum. 
 
 
In return, the BeamParticle objects give access to some 
useful methods. The beamX.xf( id, x, Q2) returns the 
standard PDF weight x f_id(x, Q^2). More interestingly, 
beamX.xfISR( iSys, id, x, Q2) returns the modified weight 
required when several subsystems have to share the energy and flavours. 
Thus iSys is added as an extra argument, and the momentum 
already assigned to the other subsystems is not available for evolution, 
i.e. the maximal x is correspondingly smaller than unity. 
Also flavour issues are handled in a similar spirit. 
 
 
An additional complication is that a parton can be either valence or 
sea, and in the latter case the BR treatment also distinguishes 
companion quarks, i.e. quark-antiquark pairs that are assumed to 
come from the same original g → q qbar branching, whether 
perturbative or not. This can be queried either with the 
beamX[iSys].companion() method, for detailed information, 
or with the beamX[iSys].isValence(), 
beamX[iSys].isUnmatched() and 
beamX[iSys].isCompanion() methods for yes/no answers 
whether a parton is valence, unmatched sea or matched sea. 
This choice should affect the ISR evolution; e.g., a valence quark 
cannot be constructed back to come from a gluon. 
 
 
To keep this info up-to-date, the beamX.pickValSeaComp() 
method should be called whenever a parton of a new flavour has been 
picked in the ISR backwards evolution, but not if the flavour has not 
been changed, since then one should not be allowed to switch back and 
forth between the same quark being considered as valence or as sea. 
Since the pickValSeaComp() method makes use of the 
current parton-density values, it should be preceded by a call 
to beamX.xfISR( iSys, id, x, Q2), where the values in 
the call are the now finally accepted ones for the newly-found mother. 
(Such a call is likely to have been made before, during the evolution, 
but is not likely to be the most recent one, i.e. still in memory, and 
therefore had better be redone.)