Implementing a New Coordinate System in LorentzVectorBase.jl

In LorentzVectorBase.jl, coordinate systems are independent of any concrete four-vector type.

This tutorial shows how to implement a light-cone coordinate system for four-momentum, so that any Lorentz vector type can use it — provided that type implements the coordinate-specific getter functions.

Light-cone coordinates

We'll define:

  • plus_component = (t + z) / √2
  • minus_component = (t - z) / √2
  • x
  • y

The coordinate-specific getters will be:

LorentzVectorBase.plus_component(v)
LorentzVectorBase.minus_component(v)
LorentzVectorBase.x(v)
LorentzVectorBase.y(v)

All other kinematic quantities (mass, pt, eta, phi, etc.) will be defined once in the coordinate system and will work for any vector type implementing the coordinate getters.

using LorentzVectorBase

1. Define the coordinate system type

Coordinate systems are singletons and must be subtypes of AbstractCoordinateSystem.

struct LightConeCoordinates <: LorentzVectorBase.AbstractCoordinateSystem end

2. Define the coordinate names

coordinate_names returns the tuple of getter function names that must be implemented for any vector type using this coordinate system.

function LorentzVectorBase.coordinate_names(::LightConeCoordinates)
  return (:plus_component, :minus_component, :x, :y)
end

3. Implement the derived kinematic functions

The coordinate system must implement all relevant getter functions listed in FOURMOMENTUM_GETTER_FUNCTIONS, except those returned by coordinate_names.

These implementations are type-generic — they take a coordinate system instance and a mom (momentum object), and call only the coordinate-specific getters (plus_component, minus_component, x, y).

const SQRT2 = sqrt(2.0)
1.4142135623730951

Cartesian component accessors

function LorentzVectorBase.t(::LightConeCoordinates, mom)
  return (LorentzVectorBase.plus_component(mom) + LorentzVectorBase.minus_component(mom)) /
         SQRT2
end
function LorentzVectorBase.z(::LightConeCoordinates, mom)
  return (LorentzVectorBase.plus_component(mom) - LorentzVectorBase.minus_component(mom)) /
         SQRT2
end

Momentum magnitudes

LorentzVectorBase.px(::LightConeCoordinates, mom) = LorentzVectorBase.x(mom)
LorentzVectorBase.py(::LightConeCoordinates, mom) = LorentzVectorBase.y(mom)
LorentzVectorBase.pz(::LightConeCoordinates, mom) = LorentzVectorBase.z(mom)
LorentzVectorBase.E(::LightConeCoordinates, mom) = LorentzVectorBase.t(mom)

function LorentzVectorBase.pt2(::LightConeCoordinates, mom)
  return LorentzVectorBase.x(mom)^2 + LorentzVectorBase.y(mom)^2
end
LorentzVectorBase.pt(::LightConeCoordinates, mom) = sqrt(LorentzVectorBase.pt2(mom))

function LorentzVectorBase.spatial_magnitude2(::LightConeCoordinates, mom)
  return LorentzVectorBase.pt2(mom) + LorentzVectorBase.pz(mom)^2
end
function LorentzVectorBase.spatial_magnitude(::LightConeCoordinates, mom)
  return sqrt(LorentzVectorBase.spatial_magnitude2(mom))
end

Mass and energy-related

function LorentzVectorBase.mass2(::LightConeCoordinates, mom)
  return LorentzVectorBase.E(mom)^2 - LorentzVectorBase.spatial_magnitude2(mom)
end
function LorentzVectorBase.mass(::LightConeCoordinates, mom)
  return sqrt(LorentzVectorBase.mass2(mom))
end

function LorentzVectorBase.boost_beta(::LightConeCoordinates, mom)
  return LorentzVectorBase.spatial_magnitude(mom) / LorentzVectorBase.E(mom)
end
function LorentzVectorBase.boost_gamma(::LightConeCoordinates, mom)
  return 1 / sqrt(1 - LorentzVectorBase.boost_beta(mom)^2)
end

function LorentzVectorBase.mt2(::LightConeCoordinates, mom)
  return LorentzVectorBase.E(mom)^2 - LorentzVectorBase.pz(mom)^2
end
LorentzVectorBase.mt(::LightConeCoordinates, mom) = sqrt(LorentzVectorBase.mt2(mom))

Angular coordinates

function LorentzVectorBase.rapidity(::LightConeCoordinates, mom)
  return 0.5 * log(
    (LorentzVectorBase.E(mom) + LorentzVectorBase.pz(mom)) /
    (LorentzVectorBase.E(mom) - LorentzVectorBase.pz(mom)),
  )
end

function LorentzVectorBase.polar_angle(::LightConeCoordinates, mom)
  return atan(LorentzVectorBase.pt(mom), LorentzVectorBase.pz(mom))
end

function LorentzVectorBase.cos_theta(::LightConeCoordinates, mom)
  return LorentzVectorBase.pz(mom) / LorentzVectorBase.spatial_magnitude(mom)
end

function LorentzVectorBase.phi(::LightConeCoordinates, mom)
  return atan(LorentzVectorBase.py(mom), LorentzVectorBase.px(mom))
end
function LorentzVectorBase.cos_phi(::LightConeCoordinates, mom)
  return LorentzVectorBase.px(mom) / LorentzVectorBase.pt(mom)
end
function LorentzVectorBase.sin_phi(::LightConeCoordinates, mom)
  return LorentzVectorBase.py(mom) / LorentzVectorBase.pt(mom)
end

4. Using the coordinate system

To use LightConeCoordinates, a Lorentz vector type needs to:

  1. Implement coordinate_system(::MyVectorType) = LightConeCoordinates()
  2. Implement the four getters listed in coordinate_names: plus_component, minus_component, x, y

Once that’s done, all the functions we defined here will work automatically.

For example, here is a simple four-vector type using light-cone coordinates:

struct MyLightConeVector
  plus::Float64
  minus::Float64
  x::Float64
  y::Float64
end

LorentzVectorBase.coordinate_system(::MyLightConeVector) = LightConeCoordinates()

LorentzVectorBase.plus_component(v::MyLightConeVector) = v.plus
LorentzVectorBase.minus_component(v::MyLightConeVector) = v.minus
LorentzVectorBase.x(v::MyLightConeVector) = v.x
LorentzVectorBase.y(v::MyLightConeVector) = v.y

LorentzVectorBase.E(MyLightConeVector(3.0, 1.0, 1.0, 2.0))  # works!
2.82842712474619

This page was generated using Literate.jl.