## Hadronic Rescattering

This page describes a model for hadronic rescattering. (Not to be confused with partonic rescattering, an optional part of the Multiparton Interactions framework.) Specifically, it is assumed that the hadrons produced can scatter against each other on the way out, before the fragmenting system has had time to expand enough that the hadrons get free. This is happening in parallel with rapid decays, i.e. mainly strong such.

A prerequisite is that the space-time production vertices of hadrons from string fragmentation are known. This was implemented in [Fer18], and is described separately on the Hadron Vertex Information page. A smaller further smearing is obtained from the Parton Vertex Information transverse displacement of separate MPI vertices. The main on/off switch for rescattering is `HadronLevel:Rescatter`, which by the default is off, since rescattering slows down the generation of events considerably, and since there are no detailed tunes with rescattering as of yet. The model requires space-time information on hadron production vertices to be set, as obtained with `Fragmentation:setVertices = on` and optionally also `PartonVertex:setVertex = on`. In some studies not all events are of interest, for example if studying jet production and no jets with sufficently high pT are produced. In those cases, it is possible to save a significant amount of time by vetoing the event before rescattering has take place, by overriding the `canVetoAfterHadronization` and `doVetoAfterHadronization` methods of the UserHooks class.

Technically, the processes here are the same as used in the Low-energy QCD Processes framework, i.e. it is the same partial cross sections and the same hadronization setup that is used in both cases. The two play different functions, however, either representing the primary collision as there or secondary rescattering collisions as here. An important part of rescattering is resonance formation. Resonance hadrons are labelled as such by setting `varWidth = on`. Such particles can then form as resonances through all of their two-body hadronic decay channels. Newly added particles with `varWidth = on` will automatically be detected upon initialization. As a practical example, a version of this framework was used to calculate the production of prompt tetraquark and pentaquark production at the LHC, assuming a molecular state model. See [Ilt21] for details.

The implementation is rather sophisticated for rescattering at low energies, where the vast majority of interactions occur. It is less appropriate at higher energies, where the lack of MPIs leads to too few hadrons being produced. The rescattering rate becomes vanishingly small before that is a problem, however. What this simplification buys is the capability to switch between different colliding hadron combinations without any need for a reinitialization.

Currently there are only a few options available:

`mode` Rescattering:impactModel (`default = 1`; `minimum = 0`; `maximum = 1`)
Impact-parameter shape of the opacity, i.e. rescattering probability, with a width determined such that the current rescattering cross section is reproduced, given the maximal opacity below.
`option` 0 : Solid disk with constant opacity out to a sharp edge.
`option` 1 : Gaussian fall-off of the opacity.

`parm` Rescattering:opacity (`default = 0.9`; `minimum = 0.`; `maximum = 1.`)
Gives the probability of scattering at impact parameter 0.

`parm` Rescattering:bMax (`default = 5.`; `minimum = 0.`; `maximum = 100.`)
Maximum allowed impact parameter for a rescattering to occur, expressed in units of fm. This cuts off the tail of a Gaussian impact-parameter profile, and more generally puts a (generous) limit on how large a cross section can become.

`parm` Rescattering:tau0RapidDecay (`default = 100.`; `minimum = 10.`)
For hadrons with a nominal invariant lifetime below this value, expressed in fm, their decays are considered in the same time-ordered sequence as rescatterings, while the rest of the decays are considered separately after the rescatterings. Note that the actual lifetime is drawn from an exponential distribution, with the nominal lifetime giving the average value.

`flag` Rescattering:scatterManyTimes (`default = on`)
When on, particles that have rescattered can scatter again.

`flag` Rescattering:quickCheck (`default = on`)
When on, a quick check is made that a pair of hadrons that is moving away from each other cannot rescatter. This is done in the CM frame of the event, not in that of the pair itself as done later. It therefore rejects a small fraction (order 10%) of rescatterings that would have been acceptable when viewed in the pair rest frame, but with a significant gain in event generation time.

`flag` Rescattering:nearestNeighbours (`default = on`)
Allow or not hadrons that have been produced as nearest neighbours on a string to rescatter against each other. There is no matter of principle to forbid it, but such effects implicitly are already included in current tunes without rescattering, so to include it will require a larger retuning effort than not to. If off also forbid hadrons that already scattered (primarily elastically) to immediately scatter against each other again.

`flag` Rescattering:delayRegeneration (`default = on`)
If on then forbid a scattered hadron from scattering again within a given regeneration time, while if off a hadron can scatter immediately afterwards. This applies to hadrons that emerge directly from the scattering, i.e. mainly in elastic and excitation. It is also relevant for the undiffracted hadron in single diffraction. Hadrons produced via string fragmentation automatically get a time delay by that. The size of the delay is given by the next parameter.

`parm` Rescattering:tauRegeneration (`default = 1.`; `minimum = 0.`; `maximum = 2.`)
When a hadron should be assigned a regeneration invariant time this is done according to an exponential with average value given by this parameter, expressed in units of fm.

`mode` Rescattering:boostDir (`default = 0`; `minimum = 0`; `maximum = 3`)
Direction of boost below, 0 off, 1 - 3 give x, y and z respectively.

`parm` Rescattering:boost (`default = 0.`)
Boosts the event before rescattering, by this many units of rapidity. For testing purposes.

`flag` Rescattering:useVelocityFrame (`default = off`)
Use center of velocity instead of center of momentum to determine rescattering origin.

`flag` Rescattering:inelastic (`default = on`)
If turned off, all rescatterings will be treated as elastic. Used primarily for model tests.

### Nucleon excitations

In rescattering, nucleon-nucleon interactions can produce resonance particles. This is implemented as N N → N X or N N → Delta X, where N is a nucleon (p or n), Delta refers to a Delta(1232) particle, and X is a nucleon excitation such as p(1520)+ or Delta(1600)+. For the sake of efficiency, the relevant cross sections are parameterized ahead of time. This is handled by the `NucleonExcitations` class.

For all excitation processes, the cross section is independent of the isospin of the involved particles. This means that the calculations can be simplified by using "id masks" of the various particles. We define the mask of a particle as its id code with the quark content removed. For example, the p(1520)+ particle (`id = 102214`) has mask 100004, which is the same for n(1520)0.

The following methods of the `NucleonExcitations` class are available.

bool NucleonExcitations::check()
run a check to validate the loaded cross section data. Returns whether successful.

vector<int> NucleonExcitations::getExcitationMasks()
search the particle database and returns a list of id masks for all implemented nucleon excitations. A particle is defined as a potential nucleon excitation if its quark content is uud (except for p+).

vector<pair<int, int>> NucleonExcitations::getChannels()
returns a list of all parameterized excitation channels. Each returned `pair` contains the masks of the two outgoing particles. For each excitation X (as defined by `getExcitationMasks`), there are two possible excitation channels, N N → N X and N N → Delta X. Note that the masks for N and Delta are `0002` and `0004`, respectively.

double NucleonExcitations::sigmaExTotal(double eCM)
returns the total excitation cross section for two nucleons colliding at the specified CM energy, using parameterized values.

double NucleonExcitations::sigmaExPartial(double eCM, int maskC, int maskD)
returns the cross section for the process N N → C D at the specified CM energy, using parameterized values.

bool NucleonExcitations::pickExcitation(int idA, int idB, double eCM, int& idCOut, double& mCOut, int& idDOut, double& mDOut)
pick an excitation channel for the incoming particles with the specified CM energy, using parameterized cross sections. If successful, the outgoing particle ids are written to `idAOut` and `idBOut`, and their corresponding masses are written to `mAOut` and `mBOut`. Returns whether successful.

double NucleonExcitations::sigmaCalc(double eCM)
double sigmaCalc(double eCM, int maskC, int maskD)
calculate the total excitation cross section or the partial cross section for the process N N → C D, without using the parameterized cross sections.

bool NucleonExcitations::parameterizeAll(int precision, double threshold = 8.)
clear all parameterized cross sections and recalculatesthem for all possible excitation channels, using excitations found with `getExcitationMasks`.

bool NucleonExcitations::save(ostream& stream)
bool NucleonExcitations::save(string file = "HadronWidths.dat")
write all parameterized cross sections in an xml format to the specified stream or file.