Utilities

Mode Filtering

class few.utils.modeselector.ModeSelector(m0mask, sensitivity_fn=None, **kwargs)

Bases: ParallelModuleBase

Filter teukolsky amplitudes based on power contribution.

This module takes teukolsky modes, combines them with their associated ylms, and determines the power contribution from each mode. It then filters the modes bases on the fractional accuracy on the total power (eps) parameter. Additionally, if a sensitivity curve is provided, the mode power is also weighted according to the PSD of the sensitivity.

The mode filtering is a major contributing factor to the speed of these waveforms as it removes large numbers of useles modes from the final summation calculation.

Be careful as this is built based on the construction that input mode arrays will in order of \(m=0\), \(m>0\), and then \(m<0\).

Parameters:
  • m0mask (1D bool xp.ndarray) – This mask highlights which modes have \(m=0\). Value is False if \(m=0\), True if not. This only includes \(m\geq0\).

  • sensitivity_fn (object, optional) – Sensitivity curve function that takes a frequency (Hz) array as input and returns the Power Spectral Density (PSD) of the sensitivity curve. Default is None. If this is not none, this sennsitivity is used to weight the mode values when determining which modes to keep. Note: if the sensitivity function is provided, and GPUs are used, then this function must accept CuPy arrays as input.

  • **kwargs (dict, optional) – Keyword arguments for the base classes: few.utils.baseclasses.ParallelModuleBase. Default is {}.

property gpu_capability

Confirms GPU capability

attributes_ModeSelector()
xp

cupy or numpy depending on GPU usage.

num_m_zero_up

Number of modes with \(m\geq0\).

Type:

int

num_m_1_up

Number of modes with \(m\geq1\).

Type:

int

num_m0

Number of modes with \(m=0\).

Type:

int

sensitivity_fn

sensitivity generating function for power-weighting.

Type:

object

property citation

Return citations related to this class.

__call__(teuk_modes, ylms, modeinds, fund_freq_args=None, eps=1e-05)

Call to sort and filer teukolsky modes.

This is the call function that takes the teukolsky modes, ylms, mode indices and fractional accuracy of the total power and returns filtered teukolsky modes and ylms.

Parameters:
  • teuk_modes (2D complex128 xp.ndarray) – Complex teukolsky amplitudes from the amplitude modules. Shape: (number of trajectory points, number of modes).

  • ylms (1D complex128 xp.ndarray) – Array of ylm values for each mode, including m<0. Shape is (num of m==0,) + (num of m>0,) + (num of m<0). Number of m<0 and m>0 is the same, but they are ordered as (m==0) first then m>0 then m<0.

  • modeinds (list of int xp.ndarrays) – List containing the mode index arrays. If in an equatorial model, need \((l,m,n)\) arrays. If generic, \((l,m,k,n)\) arrays. e.g. [l_arr, m_arr, n_arr].

  • fund_freq_args (tuple, optional) – Args necessary to determine fundamental frequencies along trajectory. The tuple will represent \((M, a, e, p, \cos\iota)\) where the large black hole mass (\(M\)) and spin (\(a\)) are scalar and the other three quantities are xp.ndarrays. This must be provided if sensitivity weighting is used. Default is None.

  • eps (double, optional) – Fractional accuracy of the total power used to determine the contributing modes. Lowering this value will calculate more modes slower the waveform down, but generally improving accuracy. Increasing this value removes modes from consideration and can have a considerable affect on the speed of the waveform, albeit at the cost of some accuracy (usually an acceptable loss). Default that gives good mismatch qualities is 1e-5.

adjust_gpu_usage(use_gpu, kwargs)

Adjust all inputs for gpu usage

If user wants to use gpu, it will change all kwargs in so that use_gpu=True.

Parameters:
  • use_gpu (bool) – If True, use gpu resources.

  • kwargs (list of dicts or dict) – List of kwargs dictionaries or single dictionary for each constituent class in the waveform generator.

attributes_ParallelModuleBase()
use_gpu

If True, use GPU.

Type:

bool

xp

Either numpy or CuPy based on gpu preference.

Type:

obj

sanity_check_gpu(use_gpu)

Check if this class has GPU capability

If the user is requesting GPU usage, this will confirm the class has GPU capabilites.

Parameters:

use_gpu (bool) – If True, the user is requesting GPU usage.

Raises:

ValueError – The user is requesting GPU usage, but this class does not have that capability.

(-2) Spin-Weighted Spherical Harmonics

class few.utils.ylm.GetYlms(assume_positive_m=False, **kwargs)

Bases: ParallelModuleBase

(-2) Spin-weighted Spherical Harmonics

The class generates (-2) spin-weighted spherical hackarmonics, \(Y_{lm}(\Theta,\phi)\). Important Note: this class also applies the parity operator (\(-1^l\)) to modes with \(m<0\).

Parameters:
  • assume_positive_m (bool, optional) – Set true if only providing \(m\geq0\), it will return twice the number of requested modes with the seconds half as modes with \(m<0\). Warning: It will also duplicate the \(m=0\) modes. Default is False.

  • **kwargs (dict, optional) – Keyword arguments for the base classes: few.utils.baseclasses.ParallelModuleBase. Default is {}.

property gpu_capability

Confirms GPU capability

attributes_GetYlms()
xp

cupy or numpy based on GPU usage.

Type:

obj

__call__(l_in, m_in, theta, phi)

Call method for Ylms.

This returns ylms based on requested \((l,m)\) values and viewing angles.

Parameters:
  • l_in (1D int xp.ndarray) – \(l\) values requested.

  • m_in (1D int xp.ndarray) – \(m\) values requested.

  • theta (double) – Polar viewing angle.

  • phi (double) – Azimuthal viewing angle.

Returns:

Ylm values.

Return type:

1D complex128 xp.ndarray

adjust_gpu_usage(use_gpu, kwargs)

Adjust all inputs for gpu usage

If user wants to use gpu, it will change all kwargs in so that use_gpu=True.

Parameters:
  • use_gpu (bool) – If True, use gpu resources.

  • kwargs (list of dicts or dict) – List of kwargs dictionaries or single dictionary for each constituent class in the waveform generator.

attributes_ParallelModuleBase()
use_gpu

If True, use GPU.

Type:

bool

xp

Either numpy or CuPy based on gpu preference.

Type:

obj

property citation

Return citations related to this module

sanity_check_gpu(use_gpu)

Check if this class has GPU capability

If the user is requesting GPU usage, this will confirm the class has GPU capabilites.

Parameters:

use_gpu (bool) – If True, the user is requesting GPU usage.

Raises:

ValueError – The user is requesting GPU usage, but this class does not have that capability.

Frequency Domain Utilities

few.utils.fdutils.get_convolution(a, b)

Calculate the convolution of two arrays.

Parameters:
  • a (1D xp.ndarray) – First array to convolve.

  • b (1D xp.ndarray) – First array to convolve.

Returns:

convolution of the two arrays.

Return type:

1D xp.ndarray

few.utils.fdutils.get_fft_td_windowed(signal, window, dt)

Calculate the Fast Fourier Transform of a windowed time domain signal.

Parameters:
  • signal (list) – A length-2 list containing the signals plus and cross polarizations.

  • window (1D xp.ndarray) – Array to be applied in time domain to each signal.

  • dt (double) – Time sampling interval of the signal and window.

Returns:

Fast Fourier Transform of the windowed time domain signals.

Return type:

list

few.utils.fdutils.get_fd_windowed(signal, window=None, window_in_fd=False)

Calculate the convolution of a frequency domain signal with a window in time domain.

Parameters:
  • signal (list) – A length-2 list containing the signals plus and cross polarizations in frequency domain.

  • window (None or 1D xp.ndarray, optional) – Array of the time domain window. If None, do not apply window. This is added for flexibility. Default is None.

  • window_in_fd (bool, optional) – If True, window is given in the frequency domain. If False, window is given in the time domain. Default is False.

Returns:

convolution of a frequency domain signal with a time domain window.

Return type:

list

class few.utils.fdutils.GetFDWaveformFromFD(waveform_generator, positive_frequency_mask, dt, non_zero_mask=None, window=None, window_in_fd=False)

Bases: object

Generic frequency domain class

This class allows to obtain the frequency domain signal given the frequency domain waveform class from the FEW package.

Parameters:
  • waveform_generator (obj) – FEW waveform class.

  • positive_frequency_mask (1D xp.ndarray) – boolean array to indicate where the frequencies are positive.

  • dt (double) – time sampling interval of the signal and window.

  • non_zero_mask (1D xp.ndarray) – boolean array to indicate where the waveform needs to be set to zero.

  • window (None or 1D xp.ndarray, optional) – Array of the time domain window. If None, do not apply window. This is added for flexibility. Default is None.

  • window_in_fd (bool, optional) – If True, window is given in the frequency domain. If False, window is given in the time domain. Default is False.

__call__(*args, **kwargs)

Run the waveform generator.

Parameters:
  • *args (tuple) – Arguments passed to waveform generator.

  • **kwargs (dict) – Keyword arguments passed to waveform generator.

Returns:

FD Waveform as [h+, hx]

Return type:

list

class few.utils.fdutils.GetFDWaveformFromTD(waveform_generator, positive_frequency_mask, dt, non_zero_mask=None, window=None)

Bases: object

Generic time domain class

This class allows to obtain the frequency domain signal given the time domain waveform class from the FEW package.

Parameters:
  • waveform_generator (obj) – FEW waveform class.

  • positive_frequency_mask (1D xp.ndarray) – boolean array to indicate where the frequencies are positive.

  • dt (double) – time sampling interval of the signal and window.

  • non_zero_mask (1D xp.ndarray) – boolean array to indicate where the waveform needs to be set to zero.

  • window (None or 1D xp.ndarray, optional) – Array of the time domain window. If None, do not apply window. This is added for flexibility. Default is None.

__call__(*args, **kwargs)

Run the waveform generator.

Parameters:
  • *args (tuple) – Arguments passed to waveform generator.

  • **kwargs (dict) – Keyword arguments passed to waveform generator.

Returns:

FD Waveform as [h+, hx] (fft from TD)

Return type:

list

Analysis and Other Tools

few.utils.utility.get_overlap(time_series_1, time_series_2, use_gpu=False)

Calculate the overlap.

Takes two time series and finds which one is shorter in length. It then shortens the longer time series if necessary. Then it performs a normalized correlation calulation on the two time series to give the overlap. The overlap of \(a(t)\) and \(b(t)\), \(\gamma_{a,b}\), is given by,

\[\gamma_{a,b} = <a,b>/(<a,a><b,b>)^{(1/2)},\]

where \(<a,b>\) is the inner product of the two time series.

Parameters:
  • time_series_1 (1D complex128 xp.ndarray) – Strain time series 1.

  • time_series_2 (1D complex128 xp.ndarray) – Strain time series 2.

  • use_gpu (bool, optional) – If True use cupy. If False, use numpy. Default is False.

few.utils.utility.get_mismatch(time_series_1, time_series_2, use_gpu=False)

Calculate the mismatch.

The mismatch is 1 - overlap. Therefore, see documentation for few.utils.utility.overlap() for information on the overlap calculation.

Parameters:
  • time_series_1 (1D complex128 xp.ndarray) – Strain time series 1.

  • time_series_2 (1D complex128 xp.ndarray) – Strain time series 2.

  • use_gpu (bool, optional) – If True use cupy. If False, use numpy. Default is False.

few.utils.utility.p_to_y(p, e, use_gpu=False)

Convert from separation \(p\) to \(y\) coordinate

Conversion from the semilatus rectum or separation \(p\) to \(y\).

Parameters:
  • p (double scalar or 1D double xp.ndarray) – Values of separation, \(p\), to convert.

  • e (double scalar or 1D double xp.ndarray) – Associated eccentricity values of \(p\) necessary for conversion.

  • use_gpu (bool, optional) – If True, use Cupy/GPUs. Default is False.

few.utils.utility.get_fundamental_frequencies(a, p, e, x)

Get dimensionless fundamental frequencies.

Determines fundamental frequencies in generic Kerr from Schmidt 2002.

Parameters:
  • a (double scalar or 1D np.ndarray) – Dimensionless spin of massive black hole. If other parameters are arrays and the spin is scalar, it will be cast to a 1D array.

  • p (double scalar or 1D double np.ndarray) – Values of separation, \(p\).

  • e (double scalar or 1D double np.ndarray) – Values of eccentricity, \(e\).

  • x (double scalar or 1D double np.ndarray) – Values of cosine of the inclination, \(x=\cos{I}\). Please note this is different from \(Y=\cos{\iota}\).

Returns:

Tuple of (OmegaPhi, OmegaTheta, OmegaR).

These are 1D arrays or scalar values depending on inputs.

Return type:

tuple

few.utils.utility.get_kerr_geo_constants_of_motion(a, p, e, x)

Get Kerr constants of motion.

Determines the constants of motion: \((E, L, Q)\) associated with a geodesic orbit in the generic Kerr spacetime.

Parameters:
  • a (double scalar or 1D np.ndarray) – Dimensionless spin of massive black hole. If other parameters are arrays and the spin is scalar, it will be cast to a 1D array.

  • p (double scalar or 1D double np.ndarray) – Values of separation, \(p\).

  • e (double scalar or 1D double np.ndarray) – Values of eccentricity, \(e\).

  • x (double scalar or 1D double np.ndarray) – Values of cosine of the inclination, \(x=\cos{I}\). Please note this is different from \(Y=\cos{\iota}\).

Returns:

Tuple of (E, L, Q).

These are 1D arrays or scalar values depending on inputs.

Return type:

tuple

few.utils.utility.xI_to_Y(a, p, e, x)

Convert from \(x_I=\cos{I}\) to \(Y=\cos{\iota}\).

Converts between the two different inclination parameters. \(\cos{I}\equiv x_I\), where \(I\) describes the orbit’s inclination from the equatorial plane. \(\cos{\iota}\equiv Y\), where \(\cos{\iota}=L/\sqrt{L^2 + Q}\).

Parameters:
  • a (double scalar or 1D np.ndarray) – Dimensionless spin of massive black hole. If other parameters are arrays and the spin is scalar, it will be cast to a 1D array.

  • p (double scalar or 1D double np.ndarray) – Values of separation, \(p\).

  • e (double scalar or 1D double np.ndarray) – Values of eccentricity, \(e\).

  • x (double scalar or 1D double np.ndarray) – Values of cosine of the inclination, \(x=\cos{I}\).

Returns:

\(Y=\cos{\iota}\) value with shape based on input shapes.

Return type:

1D array or scalar

few.utils.utility.Y_to_xI(a, p, e, Y)

Convert from \(Y=\cos{\iota}\) to \(x_I=\cos{I}\).

Converts between the two different inclination parameters. \(\cos{I}\equiv x_I\), where \(I\) describes the orbit’s inclination from the equatorial plane. \(\cos{\iota}\equiv Y\), where \(\cos{\iota}=L/\sqrt{L^2 + Q}\).

This computation may have issues near edge cases.

Parameters:
  • a (double scalar or 1D np.ndarray) – Dimensionless spin of massive black hole. If other parameters are arrays and the spin is scalar, it will be cast to a 1D array.

  • p (double scalar or 1D double np.ndarray) – Values of separation, \(p\).

  • e (double scalar or 1D double np.ndarray) – Values of eccentricity, \(e\).

  • Y (double scalar or 1D double np.ndarray) – Values of cosine of the \(\iota\).

Returns:

\(x=\cos{I}\) value with shape based on input shapes.

Return type:

1D array or scalar

few.utils.utility.get_separatrix(a, e, x)

Get separatrix in generic Kerr.

Determines separatrix in generic Kerr from Stein & Warburton 2020.

Parameters:
  • a (double scalar or 1D np.ndarray) – Dimensionless spin of massive black hole. If other parameters are arrays and the spin is scalar, it will be cast to a 1D array.

  • e (double scalar or 1D double np.ndarray) – Values of eccentricity, \(e\).

  • x (double scalar or 1D double np.ndarray) – Values of cosine of the inclination, \(x=\cos{I}\). Please note this is different from \(Y=\cos{\iota}\).

Returns:

Separatrix value with shape based on input shapes.

Return type:

1D array or scalar

few.utils.utility.get_at_t(traj_module, traj_args, bounds, t_out, index_of_interest, traj_kwargs={}, xtol=2e-12, rtol=8.881784197001252e-16)

Root finding wrapper using Brent’s method.

This function uses scipy’s brentq routine to find root.

Parameters:
  • traj_module (obj) – Instantiated trajectory module. It must output the time array of the trajectory sparse trajectory as the first output value in the tuple.

  • traj_args (list) – List of arguments for the trajectory function. p is removed. Note: It must be a list, not a tuple because the new p values are inserted into the argument list.

  • bounds (list) – Minimum and maximum values over which brentq will search for a root.

  • t_out (double) – The desired length of time for the waveform.

  • index_of_interest (int) – Index where to insert the new values in the traj_args list.

  • traj_kwargs (dict, optional) – Keyword arguments for traj_module. Default is an empty dict.

  • xtol (float, optional) – Absolute tolerance of the brentq root-finding - see :code: np.allclose() for details. Defaults to 2e-12 (scipy default).

  • rtol (float, optional) – Relative tolerance of the brentq root-finding - see :code: np.allclose() for details. Defaults to ~8.8e-16 (scipy default).

Returns:

Root value.

Return type:

double

few.utils.utility.get_p_at_t(traj_module, t_out, traj_args, index_of_p=3, index_of_a=2, index_of_e=4, index_of_x=5, bounds=None, **kwargs)

Find the value of p that will give a specific length inspiral using Brent’s method.

If you want to generate an inspiral that is a specific length, you can adjust p accordingly. This function tells you what that value of p is based on the trajectory module and other input parameters at a desired time of observation.

This function uses scipy’s brentq routine to find the (presumed only) value of p that gives a trajectory of duration t_out.

Parameters:
  • traj_module (obj) – Instantiated trajectory module. It must output the time array of the trajectory sparse trajectory as the first output value in the tuple.

  • t_out (double) – The desired length of time for the waveform.

  • traj_args (list) – List of arguments for the trajectory function. p is removed. Note: It must be a list, not a tuple because the new p values are inserted into the argument list.

  • index_of_p (int, optional) – Index where to insert the new p values in the traj_args list. Default is 3.

  • index_of_a (int, optional) – Index of a in provided traj_module arguments. Default is 2.

  • index_of_e (int, optional) – Index of e0 in provided traj_module arguments. Default is 4.

  • index_of_x (int, optional) – Index of x0 in provided traj_module arguments. Default is 5.

  • bounds (list, optional) – Minimum and maximum values of p over which brentq will search for a root. If not given, will be set to [separatrix + 0.101, 50]. To supply only one of these two limits, set the other limit to None.

  • **kwargs (dict, optional) – Keyword arguments for get_at_t().

Returns:

Value of p that creates the proper length trajectory.

Return type:

double

few.utils.utility.get_mu_at_t(traj_module, t_out, traj_args, index_of_mu=1, bounds=None, **kwargs)

Find the value of mu that will give a specific length inspiral using Brent’s method.

If you want to generate an inspiral that is a specific length, you can adjust mu accordingly. This function tells you what that value of mu is based on the trajectory module and other input parameters at a desired time of observation.

This function uses scipy’s brentq routine to find the (presumed only) value of mu that gives a trajectory of duration t_out.

Parameters:
  • traj_module (obj) – Instantiated trajectory module. It must output the time array of the trajectory sparse trajectory as the first output value in the tuple.

  • t_out (double) – The desired length of time for the waveform.

  • traj_args (list) – List of arguments for the trajectory function. p is removed. Note: It must be a list, not a tuple because the new p values are inserted into the argument list.

  • index_of_mu (int, optional) – Index where to insert the new p values in the traj_args list. Default is 1.

  • bounds (list, optional) – Minimum and maximum values of p over which brentq will search for a root. If not given, will be set to [1e-1, 1e3]. To supply only one of these two limits, set the other limit to None.

  • **kwargs (dict, optional) – Keyword arguments for get_at_t().

Returns:

Value of mu that creates the proper length trajectory.

Return type:

double

few.utils.utility.check_for_file_download(fp, few_dir, version_string=None)

Download files direct from zenodo.

This function downloads the files from zenodo as they are needed. They are downloaded based on the associated record for each version (record_by_version).

The version is determined from the __version__ attribute of few unless a version string is provided.

Parameters:
  • fp (string) – File name.

  • few_dir (string) – absolute path to FastEMRIWaveforms directory.

  • version_string (string, optional) – Provide a specific version string to get a specific dataset. Default is None.

Raises:

ValueError – Version string does not exist.

few.utils.utility.wrapper(*args, **kwargs)

Function to convert array and C/C++ class arguments to ptrs

This function checks the object type. If it is a cupy or numpy array, it will determine its pointer by calling the proper attributes. If you design a Cython class to be passed through python, it must have a ptr attribute.

If you use this function, you must convert input arrays to size_t data type in Cython and then properly cast the pointer as it enters the c++ function. See the Cython codes here for examples.

Parameters:
  • *args (list) – list of the arguments for a function.

  • **kwargs (dict) – dictionary of keyword arguments to be converted.

Returns:

(targs, tkwargs) where t indicates target (with pointer values

rather than python objects).

Return type:

Tuple

few.utils.utility.pointer_adjust(func)

Decorator function for cupy/numpy agnostic cython

This decorator applies few.utils.utility.wrapper() to functions via the decorator construction.

If you use this decorator, you must convert input arrays to size_t data type in Cython and then properly cast the pointer as it enters the c++ function. See the Cython codes here for examples.

few.utils.utility.cuda_set_device(dev)

Globally sets CUDA device

Parameters:

dev (int) – CUDA device number.

few.utils.utility.get_ode_function_options()

Get ode options.

This includes all the subinfo for each ODE derivative function that is available.

Returns:

Dictionary with all the information on available functions.

Return type:

dict

Raises:

ValueError – ODE files have not been built.