attoworld.numeric

This module will contain numerical tools.

 1"""
 2This module will contain numerical tools.
 3"""
 4
 5from .atomic_units import AtomicUnits
 6from .numeric import block_binning_1d, block_binning_2d
 7from ..attoworld_rs import (
 8    fornberg_stencil,
 9    interpolate,
10    fwhm,
11    find_first_intercept,
12    find_last_intercept,
13    find_maximum_location,
14    derivative,
15    derivative_periodic,
16)
17
18__all__ = [
19    "fornberg_stencil",
20    "find_maximum_location",
21    "fwhm",
22    "find_first_intercept",
23    "find_last_intercept",
24    "derivative",
25    "derivative_periodic",
26    "interpolate",
27    "AtomicUnits",
28    "block_binning_1d",
29    "block_binning_2d",
30]
def fornberg_stencil(order, positions, position_out=0.0, /):

Generate a finite difference stencil using the algorithm described by B. Fornberg in Mathematics of Computation 51, 699-706 (1988).

Arguments:
  • order (int): the order of the derivative
  • positions (np.ndarray): the positions at which the functions will be evaluated in the stencil. Must be larger than 2 elements in size.
  • position_out (float): the position at which using the stencil will evaluate the derivative, default 0.0.
Returns:

np.ndarray: the finite difference stencil with weights corresponding to the positions in the positions input array

Examples:
>>> stencil = fornberg_stencil(1, np.array([-1.0, 0.0, 1.0]))
>>> print(stencil)
[-0.5  0.   0.5]
def find_maximum_location(y, neighbors=3, /):

Find the location and value of the maximum of a smooth, uniformly sampled signal, interpolating to find the sub-pixel location

Arguments:
  • y (np.ndarray): The signal whose maximum should be located
  • neighbors (int): the number of neighboring points to consider in the optimization (default 3)
Returns:

(float, float): location, interpolated maximum

def fwhm(y, dx=1.0, intercept_value=0.5, neighbors=2):

Find the full-width-at-half-maximum value of a continuously-spaced distribution.

Arguments:
  • y (np.ndarray): the distribution data
  • dx (float): the x step size of the data
  • intercept_value (float): The value at which to take the intercepts (i.e. only full-width-at-HALF-max for 0.5)
  • neighbors (int): The number of neighboring points in each direction to use when constructing interpolants. Higher values are more accurate, but only for smooth data.
Returns:

float: The full width at intercept_value maximum

def find_first_intercept(y, intercept_value, neighbors):

Find the first intercept with a value

Arguments:
  • y (np.ndarray): the distribution data
  • intercept_value (float): The value at which to take the intercept
  • neighbors (int): The number of neighboring points in each direction to use when constructing interpolants. Higher values are more accurate, but only for smooth data.
Returns:

float: "index" of the intercept, a float with non-integer value, indicating where between the pixels the intercept is

def find_last_intercept(y, intercept_value, neighbors):

Find the last intercept with a value

Arguments:
  • y (np.ndarray): the distribution data
  • intercept_value (float): The value at which to take the intercept
  • neighbors (int): The number of neighboring points in each direction to use when constructing interpolants. Higher values are more accurate, but only for smooth data.
Returns:

float: "index" of the intercept, a float with non-integer value, indicating where between the pixels the intercept is

def derivative(y, order, /, neighbors=3):

Use a Fornberg stencil to take a derivative of arbitrary order and accuracy, handling the edge by using modified stencils that only use internal points.

Arguments:
  • data (np.ndarray): the data whose derivative should be taken
  • order (int): the order of the derivative
  • neighbors (int): the number of nearest neighbors to consider in each direction.
Returns:

np.ndarray: the derivative

def derivative_periodic(y, order, /, neighbors=3):

Use a Fornberg stencil to take a derivative of arbitrary order and accuracy, handling the edge by treating it as a periodic boundary

Arguments:
  • data (np.ndarray): the data whose derivative should be taken
  • order (int): the order of the derivative
  • neighbors (int): the number of nearest neighbors to consider in each direction.
Returns:

np.ndarray: the derivative

def interpolate( x_out, x_in, y_in, /, inputs_are_sorted=True, neighbors=2, extrapolate=False, derivative_order=0):

Interpolate sorted data, given a list of intersection locations

Arguments:
  • x_out (np.ndarray): array of output x values, the array onto which y_in will be interpolated
  • x_in (np.ndarray): array of input x values
  • y_in (np.ndarray): array of input y values
  • inputs_are_sorted (bool): true is x_in values are in ascending order (default). Set to false for unsorted data.
  • neighbors (int): number of nearest neighbors to include in the interpolation
  • extrapolate (bool): unless set to true, values outside of the range of x_in will be zero
  • derivative_order(int): order of derivative to take. 0 (default) is plain interpolation, 1 takes first derivative, and so on.
Returns:

np.ndarray: the interpolated y_out

class AtomicUnits:
 2class AtomicUnits:
 3    """Defines various physical constants in atomic units.
 4
 5    Attributes:
 6      meter: Atomic unit of length in meters.
 7      nm: Atomic unit of length in nanometers.
 8      second: Atomic unit of time in seconds.
 9      fs: Atomic unit of time in femtoseconds.
10      Joule: Atomic unit of energy in Joules.
11      eV: Atomic unit of energy in electronvolts.
12      Volts_per_meter: Atomic unit of electric field in V/m.
13      Volts_per_Angstrom: Atomic unit of electric field in V/Angström.
14      speed_of_light: Vacuum speed of light in atomic units.
15      Coulomb: Atomic unit of electric charge in Coulombs.
16      PW_per_cm2_au: PW/cm^2 in atomic units.
17    """
18
19    meter: float = 5.2917720859e-11
20    nm: float = 5.2917720859e-2
21    second: float = 2.418884328e-17
22    fs: float = 2.418884328e-2
23    Joule: float = 4.359743935e-18
24    eV: float = 27.21138383
25    Volts_per_meter: float = 5.142206313e11
26    Volts_per_Angstrom: float = 51.42206313
27    speed_of_light: float = 137.036
28    Coulomb: float = 1.60217646e-19
29    PW_per_cm2_au: float = 0.1553661415

Defines various physical constants in atomic units.

Attributes:
  • meter: Atomic unit of length in meters.
  • nm: Atomic unit of length in nanometers.
  • second: Atomic unit of time in seconds.
  • fs: Atomic unit of time in femtoseconds.
  • Joule: Atomic unit of energy in Joules.
  • eV: Atomic unit of energy in electronvolts.
  • Volts_per_meter: Atomic unit of electric field in V/m.
  • Volts_per_Angstrom: Atomic unit of electric field in V/Angström.
  • speed_of_light: Vacuum speed of light in atomic units.
  • Coulomb: Atomic unit of electric charge in Coulombs.
  • PW_per_cm2_au: PW/cm^2 in atomic units.
meter: float = 5.2917720859e-11
nm: float = 0.052917720859
second: float = 2.418884328e-17
fs: float = 0.02418884328
Joule: float = 4.359743935e-18
eV: float = 27.21138383
Volts_per_meter: float = 514220631300.0
Volts_per_Angstrom: float = 51.42206313
speed_of_light: float = 137.036
Coulomb: float = 1.60217646e-19
PW_per_cm2_au: float = 0.1553661415
def block_binning_1d(data: numpy.ndarray, bin: int, method: str) -> numpy.ndarray:
 5def block_binning_1d(data: np.ndarray, bin: int, method: str) -> np.ndarray:
 6    """
 7    Perform binning on an array, reducing its size by averaging (bin) blocks
 8
 9    Args:
10        data (np.ndarray): the 1d array to bin
11        bin (int): the size of bins
12        method (str): the method for averaging: ```mean``` (default) or ```median```
13
14    Returns:
15        np.ndarray: the binned data
16    """
17    new_shape = (data.shape[0] // bin, bin)
18    truncate = bin * (data.shape[0] // bin)
19    reshaped_data = data[0:truncate].reshape(new_shape)
20    match method:
21        case "median":
22            return np.median(reshaped_data, axis=1)
23        case "mean" | _:
24            return np.mean(reshaped_data, axis=1)

Perform binning on an array, reducing its size by averaging (bin) blocks

Arguments:
  • data (np.ndarray): the 1d array to bin
  • bin (int): the size of bins
  • method (str): the method for averaging: mean (default) or median
Returns:

np.ndarray: the binned data

def block_binning_2d( data: numpy.ndarray, x_bin: int = 2, y_bin: int = 2, method: str = 'mean') -> numpy.ndarray:
27def block_binning_2d(
28    data: np.ndarray, x_bin: int = 2, y_bin: int = 2, method: str = "mean"
29) -> np.ndarray:
30    """
31    Perform binning on an array, reducing its size by averaging (x_bin x y_bin) blocks
32
33    Args:
34        data (np.ndarray): the 2d array to bin
35        x_bin (int): the size of bins in the x-direction
36        y_bin (int): the size of bins in the y-direction
37        method (str): the method for averaging: ```mean``` (default) or ```median```
38
39    Returns:
40        np.ndarray: the binned data
41    """
42    new_shape = (data.shape[0] // y_bin, y_bin, data.shape[1] // x_bin, x_bin)
43    truncate_x = x_bin * (data.shape[1] // x_bin)
44    truncate_y = y_bin * (data.shape[0] // y_bin)
45    reshaped_data = data[0:truncate_y, 0:truncate_x].reshape(new_shape)
46
47    match method:
48        case "median":
49            return np.median(reshaped_data, axis=(1, 3))
50        case "mean" | _:
51            return np.mean(reshaped_data, axis=(1, 3))

Perform binning on an array, reducing its size by averaging (x_bin x y_bin) blocks

Arguments:
  • data (np.ndarray): the 2d array to bin
  • x_bin (int): the size of bins in the x-direction
  • y_bin (int): the size of bins in the y-direction
  • method (str): the method for averaging: mean (default) or median
Returns:

np.ndarray: the binned data