Source code for sofia_redux.scan.source_models.beams.asymmetry_2d
# Licensed under a 3-clause BSD style license - see LICENSE.rst
from abc import ABC
from copy import deepcopy
import numpy as np
__all__ = ['Asymmetry2D']
[docs]
class Asymmetry2D(ABC):
def __init__(self, x=None, y=None, x_weight=0.0, y_weight=0.0):
"""
Initialize an Asymmetry2D object.
The 2-dimensional asymmetry is a simple container for asymmetry
measurements of (x, y) data. It is used to provide informational
strings and significance/RMS values when requested.
Parameters
----------
x : float or numpy.ndarray
The asymmetry in the x-direction.
y : float or numpy.ndarray
The asymmetry in the y-direction.
x_weight : float or numpy.ndarray
The asymmetry weight (1/variance) in the x-direction.
y_weight : float or numpy.ndarray
The asymmetry weight (1/variance) in the y-direction.
"""
self.x = x
self.x_weight = x_weight
self.y = y
self.y_weight = y_weight
[docs]
def copy(self):
"""
Return a copy of the Asymmetry2D object.
Returns
-------
Asymmetry2D
"""
return deepcopy(self)
def __eq__(self, other):
"""
Return whether this asymmetry is equal to another.
Parameters
----------
other : Asymmetry2D
Returns
-------
bool
"""
if self is other:
return True
if not isinstance(other, Asymmetry2D):
return False
if self.x != other.x or self.y != other.y:
return False
return True
def __str__(self):
"""
Return a string representation of the asymmetry.
Returns
-------
str
"""
if self.x is None and self.y is None:
return "Asymmetry: empty"
result = 'Asymmetry: '
if isinstance(self.x, np.ndarray):
result += f'{self.x.size} planes.'
else:
if self.x is not None:
result += f'x = {self.x * 100:.3f}% +- {self.x_rms * 100:.3f}%'
if self.y is not None:
if self.x is not None:
result += ', '
result += f'y = {self.y * 100:.3f}% +- {self.y_rms * 100:.3f}%'
return result
def __repr__(self):
"""
Return a string representation of the Asymmetry instance.
Returns
-------
str
"""
return f'{object.__repr__(self)} {self}'
@property
def x_significance(self):
"""
Return the significance of the asymmetry in x.
Returns
-------
significance : float
"""
if self.x_weight is None:
return np.inf
return np.abs(self.x) * np.sqrt(self.x_weight)
@property
def y_significance(self):
"""
Return the significance of the asymmetry in x.
Returns
-------
significance : float
"""
if self.y_weight is None:
return np.inf
return np.abs(self.y) * np.sqrt(self.y_weight)
@property
def x_rms(self):
"""
Return the root-mean-square of the asymmetry in the x-direction.
Returns
-------
rms : float
"""
if self.x_weight is not None:
x_rms = np.sqrt(1 / self.x_weight)
else:
x_rms = 0.0
return x_rms
@property
def y_rms(self):
"""
Return the root-mean-square of the asymmetry in the y-direction.
Returns
-------
rms : float
"""
if self.y_weight is not None:
y_rms = np.sqrt(1 / self.y_weight)
else:
y_rms = 0.0
return y_rms