Muon g-2 from Lattice QCD using :mod:`g2tools` =============================================== .. |g2tools| replace:: :mod:`g2tools` .. |GVar| replace:: :class:`gvar.GVar` Module |g2tools| contains a small number of tools useful for analyzing contributions to the muon's magnetic moment from (lattice) QCD vacuum polarization. These tools were developed by G.P. Lepage to implement the analysis presented in Chakraborty *et al*, Phys.Rev. D89 (2014) no.11, 114501 (arXiv:1403.1778) and subsequent papers by the same authors. A typical application, illustrating the most important tools, is provided by the following code:: import g2tools as g2 import gvar as gv def main(): # data Z = gv.gvar('0.9938(17)') # current Z factor Q = 1. / 3. # charge of quark (units of proton charge) ainv = gv.gvar('1.6280(86)') # inverse lattice spacing (in GeV) G = gv.gvar([ # G(t) for t=0..63 (in lattice units) '0.0870904(11)', '0.0435138(14)', '0.00509859(48)', '0.00305614(43)', '0.00069516(19)', '0.00045466(15)', '0.000166972(80)', '0.000102219(58)', '0.000045284(34)', '0.000026213(22)', '0.000012630(14)', '7.0635(91)e-06', '3.5569(57)e-06', '1.9469(37)e-06', '1.0027(24)e-06', '5.421(16)e-07', '2.834(10)e-07', '1.5174(67)e-07', '7.943(43)e-08', '4.253(28)e-08', '2.221(19)e-08', '1.183(12)e-08', '6.132(81)e-09', '3.292(51)e-09', '1.727(34)e-09', '9.19(22)e-10', '4.81(14)e-10', '2.643(96)e-10', '1.385(64)e-10', '7.61(44)e-11', '3.92(31)e-11', '2.67(24)e-11', '2.07(21)e-11', '2.90(23)e-11', '4.12(31)e-11', '8.20(42)e-11', '1.380(65)e-10', '2.788(98)e-10', '5.01(15)e-10', '9.72(23)e-10', '1.782(34)e-09', '3.406(53)e-09', '6.333(78)e-09', '1.212(12)e-08', '2.249(18)e-08', '4.283(28)e-08', '8.016(44)e-08', '1.5263(67)e-07', '2.843(10)e-07', '5.420(16)e-07', '1.0062(25)e-06', '1.9453(39)e-06', '3.5611(58)e-06', '7.0675(93)e-06', '0.000012647(14)', '0.000026240(22)', '0.000045282(32)', '0.000102285(56)', '0.000166993(79)', '0.00045479(15)', '0.00069503(19)', '0.00305647(42)', '0.00509870(47)', '0.0435158(14)' ]) # N.B.: In general would construct G so that correlations from one t # to the next are included. Don't bother here since this is meant # just to illustrate g2tools. # compute moments, converting to physical units from lattice units mom = g2.moments(G, ainv=ainv, Z=Z, periodic=True, nlist=[4, 6, 8, 10]) print('Taylor coefficients:', g2.mom2taylor(mom)) print() # construct subtracted vac pol function using [2,2] Padé vpol = g2.vacpol(mom, order=(2,2)) # integrate vpol to get a_mu and print result amu = g2.a_mu(vpol, Q=Q) print('a_mu contribution =', amu) print() # error budget for a_mu print(gv.fmt_errorbudget( outputs=dict(a_mu=amu, mom4=mom[4]), inputs=dict(G=G, Z=Z, ainv=ainv), )) if __name__ == '__main__': main() In this code, we first read the simulation data for the *jj* correlator into array ``G``, where ``G[i]`` is the correlator for (Euclidean) time ``i/ainv`` where ``i=0,1..63``. We then use :func:`g2tools.moments` to calculate temporal moments of the correlator, while also converting from lattice units to physical units (using the inverse lattice spacing ``ainv``) and renormalizing the current (``Z``). ``vpol(q2)`` is the vacuum polarization function at Euclidean *q*\ :sup:`2` equal to ``q2``. Object ``vpol`` has type :class:`g2tools.vacpol`. It constructs a [2,2] Padé approximant from the moments, and uses that approximant to approximate the exact function. The approximants converge to the exact result as the order increases provided the momentum is space-like (``q2`` non-negative). Using a [1,1] Padé instead of [2,2] gives almost identical results here, so the approximants have converged for the present application. We calculate the contribution from vacuum polarization ``vpol`` to the muon's anomalous magnetic moment a\ :sub:`µ` using :func:`g2tools.a_mu`. We also use :func:`gvar.fmt_errorbudget` to produce an error budget for it and the 4th moment. Running this code gives the following output:: Taylor coefficients: [0.06629(74) -0.0527(11) 0.0472(15) -0.0435(18)] a_mu contribution = 5.412(57)e-09 Partial % Errors: a_mu mom4 ------------------------------ ainv: 1.00 1.06 Z: 0.34 0.34 G: 0.01 0.01 ------------------------------ total: 1.06 1.11 The contribution to the muon's anomalous magnetic moment is 54.12(57)x10\ :sup:`-10`. The error budget shows that the final uncertainty is dominated by the uncertainty in the inverse lattice spacing ``ainv``; statistical errors from ``G`` are completely negligible in this example. An alternative to using moments is to Fourier transform the correlator to obtain ``vpol(q2)`` directly. Moments are particularly useful for analyzing finite-volume and other systematic errors, but the Fourier method is simpler to code:: # compute a_mu from the Fourier transform of G(t) vpol = g2.fourier_vacpol(G, ainv=ainv, Z=Z, periodic=True) amu = g2.a_mu(vpol, Q=Q) print('a_mu contribution =', amu) print() # error budget for a_mu print(gv.fmt_errorbudget( outputs=dict(a_mu=amu), inputs=dict(G=G, Z=Z, ainv=ainv), )) This code gives identical results to that above. Both :meth:`moments` and :meth:`fourier_vacpol` can be used with filters that, for example, introduce t-windows. Setting :: vpol = g2.fourier_vacpol( G, ainv=ainv, Z=Z, periodic=True, filter=g2.TanhWin(t1=1.5, dt=0.15) ) in the previous example restricts the contributions from ``G`` to times between 0 and 1.5 fm, where the cutoff at the upper end is spread over a region of order 0.15 fm. |g2tools| is designed to work with module :mod:`gvar` which we use here to represent the statistical and systematic uncertainties in the correlator values, inverse lattice spacing, and ``Z`` factor. Each of these quantities is an object of type |GVar|, which represents a Gaussian random variable. |GVar|\s describe not only means and standard deviations, but also statistical correlations between different objects. These correlations are propagated through arbitrary arithmetic statements. Adding the following code to the end of ``main()``, for example, :: print(gv.evalcorr([mom[4], mom[6], mom[8], mom[10]])) prints out the correlation matrix for the moments, showing that they are highly correlated (as expected):: [[ 1. 0.98833867 0.9787737 0.97262094] [ 0.98833867 1. 0.99853653 0.99646438] [ 0.9787737 0.99853653 1. 0.99949934] [ 0.97262094 0.99646438 0.99949934 1. ]] The moments are also highly correlated with the final results ``a_mu``: for example, adding the following to the end of ``main()`` :: print(gv.evalcorr([a_mu, mom[4]])) gives:: [[ 1. 0.96864247] [ 0.96864247 1. ]] This kind of correlation information is used by ``gvar.fmt_errorbudget(...)`` to create the error budget. See :mod:`gvar`'s documentation for more information.