<chapter name="Semi-Internal Resonances"> 
 
<h2>Semi-Internal Resonances</h2> 
 
The introduction of a new <aloc href="SemiInternalProcesses"> 
semi-internal process</aloc> may also involve a new particle, 
not currently implemented in PYTHIA. Often it is then enough to 
use the <aloc href="ParticleDataScheme">standard machinery</aloc> 
to introduce a new particle (<code>id:all = ...</code>) and new 
decay channels (<code>id:addChannel = ...</code>). By default this 
only allows you to define a fixed total width and fixed branching 
ratios. Using <code><aloc href="ResonanceDecays">meMode</aloc></code> 
values 100 or bigger provides the possibility of a very 
simple threshold behaviour. 
 
<p/> 
If you want to have complete freedom, however, there are two 
ways to go. One is that you make the resonance decay part of the 
hard process itself, either using the 
<aloc href="LHA">Les Houches interface</aloc> or 
a semi-internal process. The other is for you to create a new 
<code>ResonanceWidths</code> object, where you write the code 
needed for a calculation of the partial width of a particular 
channel. 
 
<p/> 
Here we will explain what is involved in setting up a resonance. 
Should you actually go ahead with this, it is strongly recommended 
to use an existing resonance as a template, to get the correct 
structure. There also exists a sample main program, 
<code>main244.cc</code>, that illustrates how you could combine 
a new process and a new resonance. 
 
<p/> 
There are three steps involved in implementing a new resonance: 
<br/>1) providing the standard particle information, as already 
outlined above (<code>id:all = ...</code>, 
<code>id:addChannel = ...</code>), except that now branching 
ratios need not be specified, since they anyway will be overwritten 
by the dynamically calculated values. 
<br/>2) writing the class that calculates the partial widths. 
<br/>3) handing in a pointer to an instance of this class to PYTHIA. 
<br/>We consider the latter two aspects in turn. 
 
<h3>The ResonanceWidths Class</h3> 
 
The resonance-width calculation has to be encoded in a new class. 
The relevant code could either be put before the main program in the 
same file, or be stored separately, e.g. in a matched pair 
of <code>.h</code> and <code>.cc</code> files. The latter may be more 
convenient, in particular if the calculations are lengthy, or 
likely to be used in many different runs, but of course requires 
that these additional files are correctly compiled and linked. 
 
<p/> 
The class has to be derived  from the <code>ResonanceWidths</code> 
base class. It can implement a number of methods. The constructor 
and the <code>calcWidth</code> ones are always needed, while others 
are for convenience. Much of the administrative machinery is handled 
by methods in the base class. 
 
<p/>Thus, in particular, you must implement expressions for all 
possible final states, whether switched on in the current run or not, 
since all contribute to the total width needed in the denominator of 
the Breit-Wigner expression. Then the methods in the base class take 
care of selecting only allowed channels where that is required, and 
also of including effects of closed channels in secondary decays. 
These methods can be accessed indirectly via the 
<code><aloc href="ResonanceDecays">res...</aloc></code> 
methods of the normal 
<code><aloc href="ParticleDataScheme">particle database</aloc></code>. 
 
<p/> 
A <b>constructor</b> for the derived class obviously must be available. 
Here you are quite free to allow a list of arguments, to set 
the parameters of your model. The constructor must call the 
base-class <code>initBasic(idResIn)</code> method, where the argument 
<code>idResIn</code> is the PDG-style identity code you have chosen 
for the new resonance. When you create several related resonances 
as instances of the same class you would naturally make 
<code>idResIn</code> an argument of the constructor; for the 
PYTHIA classes this convention is used also in cases when it is 
not needed. 
<br/>The <code>initBasic(...)</code> method will 
hook up the <code>ResonanceWidths</code> object with the corresponding 
entry in the generic particle database, i.e. with the normal particle 
information you set up in point 1) above. It will store, in base-class 
member variables, a number of quantities that you later may find useful: 
<br/><code>idRes</code> : the identity code you provide; 
<br/><code>hasAntiRes</code> : whether there is an antiparticle; 
<br/><code>mRes</code> : resonance mass; 
<br/><code>GammaRes</code> resonance width; 
<br/><code>m2Res</code> : the squared mass; 
<br/><code>GamMRat</code> : the ratio of width to mass. 
 
<p/> 
A <b>destructor</b> is only needed if you require some special behaviour. 
 
<method name="void ResonanceWidths::initConstants()"> 
is called once during initialization, and can then be used to set up 
further parameters specific to this particle species, such as couplings, 
and perform calculations that need not be repeated for each new event, 
thereby saving time. This method needs not be implemented. 
</method> 
 
<method name="void ResonanceWidths::calcPreFac(bool calledFromInit = false)"> 
is called once a mass has been chosen for the resonance, but before 
a specific final state is considered. This routine can therefore 
be used to perform calculations that otherwise might have to be repeated 
over and over again in <code>calcWidth</code> below. It is optional 
whether you want to use this method, however, or put 
everything in <code>calcWidth()</code>. 
<br/>The optional argument will have the value <code>true</code> when 
the resonance is initialized, and then be <code>false</code> throughout 
the event generation, should you wish to make a distinction. 
In PYTHIA such a distinction is made for <ei>gamma^*/Z^0</ei> and 
<ei>gamma^*/Z^0/Z'^0</ei>, owing to the necessity of a special 
description of interference effects, but not for other resonances. 
<br/>In addition to the base-class member variables already described 
above, <code>mHat</code> contains the current mass of the resonance. 
At initialization this agrees with the nominal mass <code>mRes</code>, 
but during the run it will not (in general). 
</method> 
 
<method name="void ResonanceWidths::calcWidth(bool calledFromInit = false)"> 
is the key method for width calculations and returns a partial width 
value, as further described below. It is called for a specific 
final state, typically in a loop over all allowed final states, 
subsequent to the <code>calcPreFac(...)</code> call above. 
Information on the final state is stored in a number of base-class 
variables, for you to use in your calculations: 
<br/><code>iChannel</code> : the channel number in the list of 
possible decay channels; 
<br/><code>mult</code> : the number of decay products; 
<br/><code>id1, id2, id3</code> : the identity code of up to the first 
three decay products, arranged in descending order of the absolute value 
of the identity code; 
<br/><code>id1Abs, id2Abs, id3Abs</code> : the absolute value of the 
above three identity codes; 
<br/><code>mHat</code> : the current resonance mass, which is the same 
as in the latest <code>calcPreFac(...)</code> call; 
<br/><code>mf1, mf2, mf3</code> : masses of the above decay products; 
<br/><code>mr1, mr2, mr3</code> : squared ratio of the product masses 
to the resonance mass; 
<br/><code>ps</code> : is only meaningful for two-body decays, where it 
gives the phase-space factor 
<ei>ps = sqrt( (1. - mr1 - mr2)^2 - 4. * mr1 * mr2 )</ei>; 
<br/>In two-body decays the third slot is zero for the above properties. 
Should there be more than three particles in the decay, you would have 
to take care of the subsequent products yourself, e.g. using 
<br/><code>particlePtr->decay[iChannel].product(j);</code> 
<br/>to extract the <code>j</code>'th decay products (with 
<code>j = 0</code> for the first, etc.). Currently we are not aware 
of any such examples. 
<br/>The base class also contains methods for <ei>alpha_em</ei> and 
<ei>alpha_strong</ei> evaluation, and can access many standard-model 
couplings; see the existing code for examples. 
<br/>The result of your calculation should be stored in 
<br/><code>widNow</code> : the partial width of the current channel, 
expressed in GeV. 
</method> 
 
<method name="double ResonanceWidths::widthChan( double mHat, 
int idAbs1, int idAbs2)"> 
is not normally used. In PYTHIA the only exception is Higgs decays, 
where it is used to define the width (except for colour factors) 
associated with a specific incoming/outgoing state. It allows the 
results of some loop expressions to be pretabulated. 
</method> 
 
<method name="bool ResonanceWidths::allowCalc()"> 
can normally be left dummy (and then always returns <code>true</code>) but 
can optionally be used to determine whether to force dynamical width 
calculation to be switched off (return <code>false</code>). 
An example is provided by the 
<code>SUSYResonanceWidths</code> class, in which the implementation of 
this method checks for the existence of SLHA decay tables for the 
particular resonance in question, and checks if those tables should be 
given precedence over the internal width calculation. 
</method> 
 
<method name="bool ResonanceWidths::initBSM()"> 
can normally be left dummy, but for advanced implementations it 
provides a possibility to initialize data members of the derived class 
at a very early stage during initialization, before any of the other 
members are called. An example is 
provided by the <code>SUSYResonanceWidths</code> class, in which 
an internal pointer to a derived <code>Couplings</code> class must be 
(re)set before any of the other methods are used. A return value of 
<code>false</code> can be used to signal that this 
initialization step failed. 
</method> 
 
<h3>Access to resonance widths</h3> 
 
Once you have implemented a class, it is straightforward to 
make use of it in a run. Assume you have written a new class 
<code>MyResonance</code>, which inherits from 
<code>ResonanceWidths</code>. You then create an instance of 
this class and hand it in to a <code>pythia</code> object with 
<pre> 
      ResonanceWidthsPtr myResonance = make_shared&lt;MyResonance()&gt;; 
      pythia.setResonancePtr( myResonance); 
</pre> 
If you have several resonances you can repeat the procedure any number 
of times. When <code>pythia.init()</code> is called these resonances 
are initialized along with all the internal resonances, and treated in 
exactly the same manner. See also the <aloc href="ProgramFlow">Program 
Flow</aloc> 
description. 
 
<p/> 
If the code should be of good quality and general usefulness, 
it would be simple to include it as a permanently available process 
in the standard program distribution. The final step of that integration 
ought to be left for the PYTHIA authors, but basically all that is 
needed is to add one line in 
<code>ParticleData::initResonances</code>, where one creates an 
instance of the resonance in the same way as for the resonances already 
there. In addition, the particle data and decay table for the new 
resonance has to be added to the permanent 
<aloc href="ParticleData">particle database</aloc>, and the code itself 
to <code>include/ResonanceWidths.h</code> and 
<code>src/ResonanceWidths.cc</code>. 
 
<h3>Phase-Space Sampling and Kinematics</h3> 
 
The base-class <code>ResonanceDecays::pickKinematics()</code> method 
samples n-body decays isotropically in phase space. 2- and 3-body 
decays are implemented as explicit special cases. For higher-body 
decays, the algorithm relies on the so-called M-generator, see 
<ref>Bie22</ref>. 
 
<p/> 
PYTHIA also contains an implementation of the RAMBO phase-space 
generator <ref>Kle86</ref>. This is not used in the base-class 
<code>ResonanceDecays::pickKinematics()</code> method but could be 
used in derived classes (or directly from a main program). It is 
implemented as a standalone class <code>Rambo</code>, declared in 
<code>PhaseSpace.h</code>. Its main methods are briefly summarised below. 
 
<h4>RAMBO Generator</h4> 
 
An instance of the Rambo generator can be constructed and intialised 
using either 
<pre> 
  Rambo rambo; 
  rambo.initPtr( Rndm* rndmPtr ); 
</pre> 
or 
<pre> 
  Rambo rambo( Rndm* rnmdPtr ); 
</pre> 
where, in both cases, the argument, <code>rnmdPtr</code> should be a 
pointer to an instance of PYTHIA's <code>Rndm</code> class. 
 
<p/> 
You can then use the methods 
<pre> 
  double weightMassless = rambo.genPoint(double eCM, int nOut, 
    vector&lt;Vec4&gt;&amp; pOut); 
  double weightMassive  = rambo.genPoint(double eCM, vector&lt;double&gt; 
    mIn, vector&lt;Vec4&gt;&amp; pOut); 
</pre> 
to sample n-particle final-state phase spaces for massless and massive 
particles, respectively. The 
<code>double</code> output value of the methods is the relative weight 
of the sampled configuration, which is always unity if all the 
final-state particles are massless but can be non-unity for massive ones. 
 
<p/> 
In both cases, the input argument 
<code>eCM</code> denotes the total CM energy of the system of 
particles and, after each call, the output argument <code>pOut</code> 
will contain the set of generated 4-vectors, given in the 
overall CM frame of the particle system. In the massless case, the 
number of final-state momenta are specified by the input argument 
<code>nOut</code>, while in the massive case, the number of 
final-state particles is given by the size of the input vector 
<code>mIn</code> which should contain the masses (including any that 
are zero) for all of the particles. The momenta in the output vector 
<code>pOut</code> then follow the same ordering as that in 
<code>mIn</code>. 
 
</chapter> 
 
<!-- Copyright (C) 2026 Torbjorn Sjostrand --> 
