Module jidenn.data.four_vector_transform
This module contains functions to transform 4-vectors between different representations. It also contains a functions for various 4-vector operations such as boosts and rotations.
Expand source code
"""
This module contains functions to transform 4-vectors between different representations.
It also contains a functions for various 4-vector operations such as boosts and rotations.
"""
from typing import Tuple
import tensorflow as tf
import numpy as np
@tf.function
def to_e_px_py_pz(x: tf.Tensor) -> tf.Tensor:
"""Converts a 4-vector in the form (mass, pt, eta, phi) to (e, px, py, pz)
Args:
x (tf.Tensor): tensor of shape (N, 4) with (mass, pt, eta, phi)
Returns:
tf.Tensor: tensor of shape (N, 4) with (E, px, py, pz)
"""
mass, pt, eta, phi = tf.unstack(x, axis=1)
px = pt * tf.cos(phi)
py = pt * tf.sin(phi)
pz = pt * tf.tanh(eta)
E = tf.sqrt(mass**2 + px**2 + py**2 + pz**2)
return tf.stack([E, px, py, pz], axis=1)
@tf.function
def to_m_pt_eta_phi(E: tf.Tensor, px: tf.Tensor, py: tf.Tensor, pz: tf.Tensor) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor]:
"""Converts a 4-vector in the form (e, px, py, pz) to (mass, pt, eta, phi)
Args:
E (tf.Tensor): tensor of shape (N,) with energy
px (tf.Tensor): tensor of shape (N,) with px
py (tf.Tensor): tensor of shape (N,) with py
pz (tf.Tensor): tensor of shape (N,) with pz
Returns:
tf.Tensor: tensor of shape (N, 4) with (mass, pt, eta, phi)
"""
pt = tf.sqrt(px**2 + py**2)
eta = tf.math.atanh(pz / pt)
phi = tf.math.atan2(py, px)
mass = tf.sqrt(E**2 - pt**2 - pz**2)
return mass, pt, eta, phi
@tf.function
def generate_boost_matrix(phi: float, n: tf.Tensor) -> tf.Tensor:
"""Generates a boost matrix for a given rapidity and directionn n
Args:
phi (float): rapidity of the boost
n (tf.Tensor): Tensor of shape (3,) with the direction of the boost
Returns:
tf.Tensor: boost matrix
"""
B = [[tf.cosh(phi), -n[0] * tf.sinh(phi), -n[1] * tf.sinh(phi), -n[2] * tf.sinh(phi)],
[-n[0] * tf.sinh(phi), 1 + (n[0]**2) * (tf.cosh(phi) - 1), n[0] * n[1]
* (tf.cosh(phi) - 1), n[0] * n[2] * (tf.cosh(phi) - 1)],
[-n[1] * tf.sinh(phi), n[1] * n[0] * (tf.cosh(phi) - 1), 1 + (n[1]**2)
* (tf.cosh(phi) - 1), n[1] * n[2] * (tf.cosh(phi) - 1)],
[-n[2] * tf.sinh(phi), n[2] * n[0] * (tf.cosh(phi) - 1), n[2] * n[1] * (tf.cosh(phi) - 1), 1 + (n[2]**2) * (tf.cosh(phi) - 1)]]
return tf.convert_to_tensor(B, dtype=tf.float32)
@tf.function
def boost(x: tf.Tensor, boost_matrix: tf.Tensor) -> tf.Tensor:
"""Boosts a 4-vector x by a boost matrix
Args:
x (tf.Tensor): tensor of shape (N, 4) with (E, px, py, pz)
boost_matrix (tf.Tensor): boost matrix
Returns:
tf.Tensor: boosted tensor of shape (N, 4) with (E, px, py, pz)
"""
return tf.einsum('ij,aj->ai', boost_matrix, x)
@tf.function
def rotate(x: tf.Tensor, rotation_matrix: tf.Tensor) -> tf.Tensor:
"""Rotates multiple 4-vectors (E,px,py,pz) x by rotation_matrix
Args:
x (tf.Tensor): Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be rotated
rotation_matrix (tf.Tensor): Tensor of shape (3, 3) containing the rotation matrix
Returns:
tf.Tensor: Tensor of shape (N, 4) containing the rotated 4-vectors
"""
return tf.concat([x[:, 0:1], tf.einsum("ij,jk->ik", x[:, 1:], rotation_matrix)], axis=1)
@tf.function
def generate_rotation_matrix(theta: float, n: tf.Tensor) -> tf.Tensor:
"""Generates a rotation matrix for a rotation around an arbitrary axis
Args:
theta (float): The angle to rotate by
n (tf.Tensor): The axis to rotate around of shape (3,)
Returns:
tf.Tensor: The rotation matrix of shape (3, 3)
"""
R = [[tf.cos(theta) + n[0] ** 2 * (1 - tf.cos(theta)), n[0] * n[1] * (1 - tf.cos(theta)) - n[2] * tf.sin(theta), n[0] * n[2] * (1 - tf.cos(theta)) + n[1] * tf.sin(theta)],
[n[1] * n[0] * (1 - tf.cos(theta)) + n[2] * tf.sin(theta), tf.cos(theta) + n[1] ** 2 *
(1 - tf.cos(theta)), n[1] * n[2] * (1 - tf.cos(theta)) - n[0] * tf.sin(theta)],
[n[2] * n[0] * (1 - tf.cos(theta)) - n[1] * tf.sin(theta), n[2] * n[1] * (1 - tf.cos(theta)) + n[0] * tf.sin(theta), tf.cos(theta) + n[2] ** 2 * (1 - tf.cos(theta))]]
R = tf.convert_to_tensor(R)
return R
@tf.function
def random_lorentz_transform(x: tf.Tensor) -> tf.Tensor:
"""Randomly applies a lorentz transform to multiple 4-vectors (E,px,py,pz) x
Args:
x (tf.Tensor): Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be transformed
Returns:
tf.Tensor: Tensor of shape (N, 4) containing the transformed 4-vectors
"""
# Randomly generate rapidity phi
phi = tf.random.uniform(shape=(), minval=-1, maxval=1, dtype=tf.float32)
phi = tf.math.atanh(phi)
# Randomly generate direction n_b
n_b = tf.random.normal(shape=(3,), dtype=tf.float32)
n_b = n_b / tf.norm(n_b)
# Randomly generate theta
theta = tf.random.uniform(shape=(), minval=0, maxval=2 * np.pi)
# Randomly generate n for rotation
n_r = tf.random.uniform(shape=(3,), minval=-1, maxval=1)
n_r = n_r / tf.norm(n_r)
# Generate rotation matrix
R = generate_rotation_matrix(theta, n_r)
#
B = generate_boost_matrix(phi, n_b)
# Apply rotation
# x = rotate(x, R)
# Apply boost
x = boost(x, B)
return x
@tf.function
def lorentz_dot_product(x: tf.Tensor, y: tf.Tensor) -> tf.Tensor:
"""Calculate the lorentz dot product (+,-,-,-) of two 4-vectors
Args:
x (tf.Tensor): Tensor of shape (N, 4) containing the first 4-vectors
y (tf.Tensor): Tensor of shape (N, 4) containing the second 4-vectors
Returns:
tf.Tensor: Tensor of shape (N, N) containing the lorentz dot product of
"""
metric = tf.convert_to_tensor([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1]], dtype=tf.float32)
return tf.einsum('nj,jk,mk->nm', x, metric, y)
Functions
def boost(x: tensorflow.python.framework.ops.Tensor, boost_matrix: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Boosts a 4-vector x by a boost matrix
Args
x
:tf.Tensor
- tensor of shape (N, 4) with (E, px, py, pz)
boost_matrix
:tf.Tensor
- boost matrix
Returns
tf.Tensor
- boosted tensor of shape (N, 4) with (E, px, py, pz)
Expand source code
@tf.function def boost(x: tf.Tensor, boost_matrix: tf.Tensor) -> tf.Tensor: """Boosts a 4-vector x by a boost matrix Args: x (tf.Tensor): tensor of shape (N, 4) with (E, px, py, pz) boost_matrix (tf.Tensor): boost matrix Returns: tf.Tensor: boosted tensor of shape (N, 4) with (E, px, py, pz) """ return tf.einsum('ij,aj->ai', boost_matrix, x)
def generate_boost_matrix(phi: float, n: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Generates a boost matrix for a given rapidity and directionn n
Args:
phi (float): rapidity of the boost n (tf.Tensor): Tensor of shape (3,) with the direction of the boostReturns
tf.Tensor
- boost matrix
Expand source code
@tf.function def generate_boost_matrix(phi: float, n: tf.Tensor) -> tf.Tensor: """Generates a boost matrix for a given rapidity and directionn n Args: phi (float): rapidity of the boost n (tf.Tensor): Tensor of shape (3,) with the direction of the boost Returns: tf.Tensor: boost matrix """ B = [[tf.cosh(phi), -n[0] * tf.sinh(phi), -n[1] * tf.sinh(phi), -n[2] * tf.sinh(phi)], [-n[0] * tf.sinh(phi), 1 + (n[0]**2) * (tf.cosh(phi) - 1), n[0] * n[1] * (tf.cosh(phi) - 1), n[0] * n[2] * (tf.cosh(phi) - 1)], [-n[1] * tf.sinh(phi), n[1] * n[0] * (tf.cosh(phi) - 1), 1 + (n[1]**2) * (tf.cosh(phi) - 1), n[1] * n[2] * (tf.cosh(phi) - 1)], [-n[2] * tf.sinh(phi), n[2] * n[0] * (tf.cosh(phi) - 1), n[2] * n[1] * (tf.cosh(phi) - 1), 1 + (n[2]**2) * (tf.cosh(phi) - 1)]] return tf.convert_to_tensor(B, dtype=tf.float32)
def generate_rotation_matrix(theta: float, n: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Generates a rotation matrix for a rotation around an arbitrary axis
Args
theta
:float
- The angle to rotate by
n
:tf.Tensor
- The axis to rotate around of shape (3,)
Returns
tf.Tensor
- The rotation matrix of shape (3, 3)
Expand source code
@tf.function def generate_rotation_matrix(theta: float, n: tf.Tensor) -> tf.Tensor: """Generates a rotation matrix for a rotation around an arbitrary axis Args: theta (float): The angle to rotate by n (tf.Tensor): The axis to rotate around of shape (3,) Returns: tf.Tensor: The rotation matrix of shape (3, 3) """ R = [[tf.cos(theta) + n[0] ** 2 * (1 - tf.cos(theta)), n[0] * n[1] * (1 - tf.cos(theta)) - n[2] * tf.sin(theta), n[0] * n[2] * (1 - tf.cos(theta)) + n[1] * tf.sin(theta)], [n[1] * n[0] * (1 - tf.cos(theta)) + n[2] * tf.sin(theta), tf.cos(theta) + n[1] ** 2 * (1 - tf.cos(theta)), n[1] * n[2] * (1 - tf.cos(theta)) - n[0] * tf.sin(theta)], [n[2] * n[0] * (1 - tf.cos(theta)) - n[1] * tf.sin(theta), n[2] * n[1] * (1 - tf.cos(theta)) + n[0] * tf.sin(theta), tf.cos(theta) + n[2] ** 2 * (1 - tf.cos(theta))]] R = tf.convert_to_tensor(R) return R
def lorentz_dot_product(x: tensorflow.python.framework.ops.Tensor, y: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Calculate the lorentz dot product (+,-,-,-) of two 4-vectors
Args
x
:tf.Tensor
- Tensor of shape (N, 4) containing the first 4-vectors
y
:tf.Tensor
- Tensor of shape (N, 4) containing the second 4-vectors
Returns
tf.Tensor
- Tensor of shape (N, N) containing the lorentz dot product of
Expand source code
@tf.function def lorentz_dot_product(x: tf.Tensor, y: tf.Tensor) -> tf.Tensor: """Calculate the lorentz dot product (+,-,-,-) of two 4-vectors Args: x (tf.Tensor): Tensor of shape (N, 4) containing the first 4-vectors y (tf.Tensor): Tensor of shape (N, 4) containing the second 4-vectors Returns: tf.Tensor: Tensor of shape (N, N) containing the lorentz dot product of """ metric = tf.convert_to_tensor([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1]], dtype=tf.float32) return tf.einsum('nj,jk,mk->nm', x, metric, y)
def random_lorentz_transform(x: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Randomly applies a lorentz transform to multiple 4-vectors (E,px,py,pz) x
Args
x
:tf.Tensor
- Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be transformed
Returns
tf.Tensor
- Tensor of shape (N, 4) containing the transformed 4-vectors
Expand source code
@tf.function def random_lorentz_transform(x: tf.Tensor) -> tf.Tensor: """Randomly applies a lorentz transform to multiple 4-vectors (E,px,py,pz) x Args: x (tf.Tensor): Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be transformed Returns: tf.Tensor: Tensor of shape (N, 4) containing the transformed 4-vectors """ # Randomly generate rapidity phi phi = tf.random.uniform(shape=(), minval=-1, maxval=1, dtype=tf.float32) phi = tf.math.atanh(phi) # Randomly generate direction n_b n_b = tf.random.normal(shape=(3,), dtype=tf.float32) n_b = n_b / tf.norm(n_b) # Randomly generate theta theta = tf.random.uniform(shape=(), minval=0, maxval=2 * np.pi) # Randomly generate n for rotation n_r = tf.random.uniform(shape=(3,), minval=-1, maxval=1) n_r = n_r / tf.norm(n_r) # Generate rotation matrix R = generate_rotation_matrix(theta, n_r) # B = generate_boost_matrix(phi, n_b) # Apply rotation # x = rotate(x, R) # Apply boost x = boost(x, B) return x
def rotate(x: tensorflow.python.framework.ops.Tensor, rotation_matrix: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Rotates multiple 4-vectors (E,px,py,pz) x by rotation_matrix
Args
x
:tf.Tensor
- Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be rotated
rotation_matrix
:tf.Tensor
- Tensor of shape (3, 3) containing the rotation matrix
Returns
tf.Tensor
- Tensor of shape (N, 4) containing the rotated 4-vectors
Expand source code
@tf.function def rotate(x: tf.Tensor, rotation_matrix: tf.Tensor) -> tf.Tensor: """Rotates multiple 4-vectors (E,px,py,pz) x by rotation_matrix Args: x (tf.Tensor): Tensor of shape (N, 4), where N is the number of 4-vectors of shape (E,px,py,pz) to be rotated rotation_matrix (tf.Tensor): Tensor of shape (3, 3) containing the rotation matrix Returns: tf.Tensor: Tensor of shape (N, 4) containing the rotated 4-vectors """ return tf.concat([x[:, 0:1], tf.einsum("ij,jk->ik", x[:, 1:], rotation_matrix)], axis=1)
def to_e_px_py_pz(x: tensorflow.python.framework.ops.Tensor) ‑> tensorflow.python.framework.ops.Tensor
-
Converts a 4-vector in the form (mass, pt, eta, phi) to (e, px, py, pz)
Args
x
:tf.Tensor
- tensor of shape (N, 4) with (mass, pt, eta, phi)
Returns
tf.Tensor
- tensor of shape (N, 4) with (E, px, py, pz)
Expand source code
@tf.function def to_e_px_py_pz(x: tf.Tensor) -> tf.Tensor: """Converts a 4-vector in the form (mass, pt, eta, phi) to (e, px, py, pz) Args: x (tf.Tensor): tensor of shape (N, 4) with (mass, pt, eta, phi) Returns: tf.Tensor: tensor of shape (N, 4) with (E, px, py, pz) """ mass, pt, eta, phi = tf.unstack(x, axis=1) px = pt * tf.cos(phi) py = pt * tf.sin(phi) pz = pt * tf.tanh(eta) E = tf.sqrt(mass**2 + px**2 + py**2 + pz**2) return tf.stack([E, px, py, pz], axis=1)
def to_m_pt_eta_phi(E: tensorflow.python.framework.ops.Tensor, px: tensorflow.python.framework.ops.Tensor, py: tensorflow.python.framework.ops.Tensor, pz: tensorflow.python.framework.ops.Tensor) ‑> Tuple[tensorflow.python.framework.ops.Tensor, tensorflow.python.framework.ops.Tensor, tensorflow.python.framework.ops.Tensor, tensorflow.python.framework.ops.Tensor]
-
Converts a 4-vector in the form (e, px, py, pz) to (mass, pt, eta, phi)
Args
E
:tf.Tensor
- tensor of shape (N,) with energy
px
:tf.Tensor
- tensor of shape (N,) with px
py
:tf.Tensor
- tensor of shape (N,) with py
pz
:tf.Tensor
- tensor of shape (N,) with pz
Returns
tf.Tensor
- tensor of shape (N, 4) with (mass, pt, eta, phi)
Expand source code
@tf.function def to_m_pt_eta_phi(E: tf.Tensor, px: tf.Tensor, py: tf.Tensor, pz: tf.Tensor) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor]: """Converts a 4-vector in the form (e, px, py, pz) to (mass, pt, eta, phi) Args: E (tf.Tensor): tensor of shape (N,) with energy px (tf.Tensor): tensor of shape (N,) with px py (tf.Tensor): tensor of shape (N,) with py pz (tf.Tensor): tensor of shape (N,) with pz Returns: tf.Tensor: tensor of shape (N, 4) with (mass, pt, eta, phi) """ pt = tf.sqrt(px**2 + py**2) eta = tf.math.atanh(pz / pt) phi = tf.math.atan2(py, px) mass = tf.sqrt(E**2 - pt**2 - pz**2) return mass, pt, eta, phi