Package: pymule
pyMuleMcMule is a framework for fully differential higher-order QED
calculations of scattering and decay processes involving leptons. It
keeps finite lepton masses, which regularises collinear singularities.
Soft singularities are treated with dimensional regularisation and
using ${\rm FKS}^\ell$ subtractionPlease find the manual for McMulehereor download it hereas a
pdfIf you find McMule useful, please consider citing[2007.01654]QED at NNLO with McMuleP. Banerjee, T. Engel, A. Signer, Y. UlrichThis is the analysis tool for McMule supporting Python 2 and Python 3.Installationpymulecan be installed with pip as# For python 2pipinstallgit+https://gitlab.com/mule-tools/pymule.git# For python 3pip3installgit+https://gitlab.com/mule-tools/pymule.gitIn principle this takes care of everything. However, it is usually
better to installnumpyandscipyfirst by handpipinstallnumpy
pipinstallscipy
pipinstallgit+https://gitlab.com/mule-tools/pymule.gitFurther, Jupyter or IPython are strongly recommended. A pre-built
Docker image is available atyulrich/pymule.For further details please refer to the McMule manualhereor download it hereas a pdfExample analysisExamples of analysis can be found in the user-library atmule-tools/user-library.Nevertheless, we repeat here the analysis the example analysis of the
paperradiative-lepton-decay/babar/exampleWe begin by loadingpymuleand initialising the $\tau$ lifetimefrompymuleimport*# To normalise branching ratios, we need the tau lifetimelifetime=1/(1000*(6.582119e-25)/(2.903e-13))Next, we need to pointpymuleto the output directory ofmcmulewith thesetupcommand. In our example this isbabar-tau-e/out.
This could either be a real directory or atarfile# The folder where McMule has stored the statefilessetup(folder='babar-tau-e/out/')As a next step, we import the LO and NLOwhich_piecesand combine
them using two centralpymulecommands:sigmaandmergefks.sigmatakes thewhich_pieceas an argument and imports matching
results, already merging different random seeds.mergefkstakes the
results of (multiple)sigmainvocations, adds results with matching
$\xi_\text{cut}$ values and combines the result.While it is not strictly necessary to use this at LO, we still do.# Import LO data and re-scale to branching ratioLO=scaleset(mergefks(sigma('m2enng0')),GF**2*lifetime*alpha)# Import NLO corrections from the three piecesNLO=scaleset(mergefks(sigma('m2enngR'),# real correctionssigma('m2enngCT'),# counter termanyxi=sigma('m2enngV')# virtual corrections),GF**2*lifetime*alpha**2)In the present case, $\sigma_n^{(1)}$ is split into multiple
contributions, namelym2enngVandm2enngC.  This is indicated by
theanyxiargument.Users should keep in mind that McMule ships with a version ofglobal_defwhere the couplings $G_F={\tt GF}$ and $\alpha={\tt alpha}$ are set to $G_F=\alpha=1$. Hence, we usepymule's
functionscalesetto multiply the result with the correct values of
$G_F$ (in ${\rm MeV}^{-1}$) and $\alpha$ (in the OS scheme).Next, we can calculate the total branching ratio by adding up the LO
and NLO branching ratios usingplusnumbers# The branching ratio at NLO = LO + correctionfullNLO=plusnumbers(LO['value'],NLO['value'])# Print resultsprint"BR_0 = ",printnumber(LO['value'])print"dBR  = ",printnumber(NLO['value'])print"BR_1 = ",printnumber(fullNLO)Next, we usekplotto produce plots# Produce energy plotfig1,(ax1,ax2)=kplot({'lo':LO['Ee'],'nlo':NLO['Ee']},labelx=r"$E_e\,/\,{\rm MeV}$",labelsigma=r"$\D\mathcal{B}/\D E_e$")ax2.set_ylim(0.8,1.01)# Produce visible mass plotfig2,(ax1,ax2)=kplot({'lo':LO['minv'],'nlo':NLO['minv']},labelx=r"$m_{e\gamma}\,/\,{\rm MeV}$",labelsigma=r"$\D\mathcal{B}/\D m_{e\gamma}$")ax1.set_yscale('log')ax1.set_xlim(1000,0)ax1.set_ylim(5e-9,1e-3)ax2.set_ylim(0.8,1.)ReferenceMost functions inpymulehavedocstringsmeaning that help can be
accessed as>>> help(pymule.sigma) # Python
Help on function sigma in module pymule.loader:

sigma(piece, **kwargs)
    sigma(piece, **kwargs) loads the which_piece piece and
    statistically combines the random seeds. It returns a dict
    with the tuples of FKS parameters as keys.
    ....

In [2]: ?pymule.sigma # IPython

Signature: pymule.sigma(piece, **kwargs)
Docstring:
sigma(piece, **kwargs) loads the which_piece piece and
statistically combines the random seeds. It returns a dict
with the tuples of FKS parameters as keys.
....Data structureInpymulewe store data using eitherdictornp.arrayas
follows.Numbers $y\pm e$ are stored asnp.array([y,e])Histograms $\{ (x_i, y_i\pm e_i) \}$ are stores similarly asnp.arraywith the $x_i$ indicating the centre of the bin. Over-
and underflow bins are marked withnp.infnp.array([[x1,y1,e1],[x2,y2,e2],[x3,y3,e3],...])Dataset, i.e. results of runs (either as the result ofimportvegasormergefks), aredictwith keystime: the job's run timevalue: the best estimate for the cross section and its errorchi2a: the $\chi^2$ estimate of the integratorall histograms as specified by theirname(..)inuser.f95msg: any message. Usually this contains information on the
state of the integrator (not present in combined results)SHA: the first 5 characters of the source-tree's SHA1 hash at
compile time (not present in combined results)iteration: the number of iterations completed in this file
(not present in combined results)Non-combined datasets (such as the result ofsigma(..)) are dicts
of datasets with the FKS parameters (or more generally the groups
returned by the filename matching) as keys.