openloops is hosted by Hepforge, IPPP Durham

Native OpenLoops Fortran interface

OpenLoops offers an easy-to-use native interface which can be used in any Fortran90 or C/C++ program. In the following we illustrate the relevant routines and their arguments as used in a Fortran90 program. An explicit examples can be found below. A corresponding documentation for the C/C++ interface can be found here.

In a Fortran90 program the OpenLoops interface is loaded via the module

use openloops


Any parameter can be set via the routine

set_parameter(parameter, value, error)
  character(*), intent(in) :: parameter
  TYPE, intent(in) :: value
  integer, intent(out), optional :: error

Here, TYPE can either be integer, double or character(*) according to the parameter to be set.

Similiarly, the value of a parameter can be obtained via the routine

call get_parameter(parameter, value, error)
  character(*), intent(in) :: parameter
  TYPE, intent(out) :: value
  integer, intent(out), optional :: error

Before the first phase-space point is actually calculated OpenLoops has to be initialized via

call start()

Process registration

At the beginning of a run all required amplitudes have to be registered via the function

register_process(process, amptype)
  character(*), intent(in) :: process
  integer, intent(in) :: amptype
  integer :: register_process

Here, the process is given in the format "PDG(i1) PDG(i2) -> PDG(f1) PDG(f2) ...", with the respective PDG codes of the initial/final state particles. The type of the registered amplitude has to be specified via the argument TYPE: 1=Tree, 11=Loop, 12=LoopInduced. Note, that amplitudes of type 11 always also include the corresponding squared tree amplitudes and, as do amplitudes of type 1, also always the corresponding color- and spin-correlated amplitudes. The return value is a unique id for any registered amplitude. Amplitudes for different permutations of external particles should be registered independently.

When a process is registered the required coupling order should have been set before, specifying the coupling which is kept fixed, i.e. for a NLO QCD amplitude the EW coupling of the squared amplitude should be specified via

call set_parameter(order_ew, O(α))

For example the O(αs3α) one-loop matrix element and the corresponding O(αs2α) tree matix element for dd ➞ Zuu can be registered via

call set_parameter(order_ew, 1)
id = register_process("1 -1 -> 23 2 -2", 11)

Note: currently only O(αs) NLO QCD corrections are available in OpenLoops. In the future also O(α) NLO EW corrections will become available and can be registered specifying the in this case fixed order_qcd.


For the calculation of amplitudes with N external particles phase-space points have to be passed in the format p_ex(4:N). The following routine yields a random phase-space point with the kinematics of process id using Rambo

phase_space_point(id , sqrt_s, p_ex)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: sqrt_s
  real(REALKIND), intent(out) :: p_ex(4,N)

An actual amplitude for a process registered as id can be calculated with one of the following routines. All results are summed (and averaged in the case of initial states) over external-particle helicities and colours.


evaluate_tree(id, p_ex, m2lo)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  real(REALKIND), intent(out) :: m2lo

gives as result m2lo the corresponding squared tree amplitude.

Color-correlated tree

call evaluate_cc(id, p_ex, m2tree, m2cc, m2ew)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  real(REALKIND), intent(out) :: m2tree
  real(REALKIND), intent(out) :: m2cc(N*(N-1)/2)
  real(REALKIND), intent(out) :: m2ew

gives as results m2tree, m2cc and m2ew the tree amplitude, the N*(N-1)/2 corresponding independent color-correlated squared tree amplitudes Cij = <M|TiTj|M> in the BLHA convention, i.e., the element at position i+j(j-1)/2+1 (counting external legs from zero) contains the result for Cij with 0 ≤ i < j ≤ N-1i; and the charge correlated tree amplitude.

Spin-correlated tree

call evaluate_sc(id, p_ex, emitter, polvect, m2sc)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  integer, intent(in) :: emitter
  real(REALKIND), intent(in) :: polvect(4)
  real(REALKIND), intent(out) :: m2sc(N)

gives as result m2sc(j) the corresponding spin-correlated squared tree amplitude for each spectator j and a given emitter with polarisation vector polvect.


evaluate_loop(id, p_ex, m2lo, m2l1, acc)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  real(REALKIND), intent(out) :: m2lo
  real(REALKIND), intent(out) :: m2l1(0:2)
  real(REALKIND), intent(out) :: acc

gives as result m2lo and m2l1 respectivly the squared tree and (UV renormalised) tree-one-loop interference amplitudes, where m2l1(0) yields the finite part and m2l1(1) and m2l1(2) the residues of the single and double poles in ε=(4-D)/2. By default the BLHA normalisation convention is used, i.e. an overall normalisation factor (4π)ε/Γ(1-ε) is implicitly understood. An accuracy measure of the corresponding amplitude is returned as acc if available, -1 otherwise.

UV counter-term

call evaluate_ct(id, p_ex, m2lo, m2ct)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  real(REALKIND), intent(out) :: m2lo
  real(REALKIND), intent(out) :: m2ct

gives as result m2lo and m2ct respectively the squared tree and tree-one-loop interference UV counter-term amplitudes.

Squared one-loop

evaluate_loop2(id, p_ex, m2l2, acc)
  integer, intent(in) :: id
  real(REALKIND), intent(in) :: p_ex(4,N)
  real(REALKIND), intent(out) :: m2l2
  real(REALKIND), intent(out) :: acc

gives as result m2l2 the squared one-loop amplitude for a loop-induced processes.


At the end of a run OpenLoops cleans up its memory and possibly writes log files via

call finish()


Explicit Fortran90 example

The following example calculates the one-loop matrix element of the process dd ➞ Zuu for a random phase-space point. The required library has to be downloaded before via

./openloops libinstall ppzjj

program main
  use openloops
  implicit none
  integer :: id, error, k
  real(8) :: m2_tree, m2_loop(0:2), acc
  real(8) :: p_ex(0:3,5)
  real(8) :: mZ = 91.2
  real(8) :: mu = 100, alpha_s = 0.1, energy=1000

  ! coupling order alpha_ew^1, implies QCD correction for loop process
  call set_parameter("order_ew", 1)

  ! set Z mass
  call set_parameter("mass(23)", mZ)

  ! Increase verbosity level to list loaded libraries
  call set_parameter("verbose", 1)

  ! register one-loop amplitude for process d dbar -> Z u ubar
  ! The "ppzjj" process library must be installed before via
  ! $ ./scons auto=ppzjj
  ! second argument of register_process:
  ! 1 for tree-like matrix elements (tree, color and spin correlations),
  ! 11 for loop, 12 for loop^2
  id = register_process("1 -1 -> 23 2 -2", 11)

  ! start
  call start()

  if (id > 0) then
    ! generate a random phase space point with rambo
    call phase_space_point(id, energy, p_ex)

    ! set strong coupling
    call set_parameter("alpha_s", alpha_s)
    ! set renormalisation scale
    call set_parameter("mu", mu)

    print *
    print *, "Tree and loop matrix element of the process"
    print *, "d dbar -> Z u ubar"
    print *, "for the phase-space point"
    do k = 1, size(p_ex,2)
      print *, 'P[', int(k,1), '] =', p_ex(:,k)
    end do

    ! evaluate tree matrix element
    call evaluate_tree(id, p_ex, m2_tree)
    ! print tree result
    print *
    print *, "evaluate_tree"
    print *, "Tree:       ", m2_tree

    ! evaluate tree and loop matrix elements
    call evaluate_loop(id, p_ex, m2_tree, m2_loop(0:2), acc)
    ! print loop result
    print *
    print *, "evaluate_loop"
    print *, "Tree:       ", m2_tree
    print *, "Loop ep^0:  ", m2_loop(0)
    print *, "Loop ep^-1: ", m2_loop(1)
    print *, "Loop ep^-2: ", m2_loop(2)
    print *, "accuracy:   ", acc
    print *
  end if

  ! finish
  call finish()

end program main

This example can also be found inside the file ./examples/OL_interface.f90 of the OpenLoops installation and can be compiled via:

cd ./example
gfortran -o OL_fortran.o -c -O2 -I../lib_src/openloops/mod OL_fortran.f90
gfortran -o OL_fortran -Wl,-rpath=../lib OL_fortran.o -L../lib -lopenloops

or with our SCons build system via

cd ./example
../scons OL_fortran