Waveform

class GWFrames.Waveform

A gravitational waveform, decomposed into spin-weighted spherical harmonics.

A Waveform stores the complex mode data of a single waveform as functions of time, together with the \((\ell, m)\) values of the modes and the frame with respect to which the modes are decomposed. It also records the spin weight and boost weight of the data, the frame type and data type, whether the radius and the mass have been scaled out of the data, and a history of the operations applied to the object. Its methods provide the manipulations needed in waveform analysis: slicing and interpolation in time; rotations and transformations to the coprecessing, corotating, and inertial frames; alignment, comparison, and hybridization; and evaluation on the sphere.

The frame data are unit quaternions (rotors). The rotor at each time takes the standard basis \((x, y, z)\) into the basis \((X, Y, Z)\) with respect to which the modes are decomposed. If there are no frame data, the modes are decomposed with respect to the standard basis; if there is a single rotor, the frame is constant; otherwise there is one rotor for each time step.

Two waveforms with the same times and in the same frame may be added or subtracted with + and -, which act mode by mode, or multiplied or divided with * and /, which act pointwise on the sphere. The spin weight of a product is the sum of the spin weights of the factors, and that of a quotient is their difference. The result has every mode from \(\ell = |s|\), where \(s\) is its spin weight, up to the smaller of the largest \(\ell\) values of the two inputs. Every mode of both inputs is used, and the pointwise values are computed on a grid that resolves modes up to the sum of those largest \(\ell\) values, so the modes of a product are exact, and any higher modes of the product are simply omitted. A quotient is generally not band-limited, so its modes are only approximate. A waveform may also be multiplied or divided by a float.

A Waveform may be constructed in any of these ways:

Waveform()

An empty waveform.

Waveform(W)

A copy of the waveform W, including its history.

Waveform(FileName, DataFormat)

The data in the text file FileName. Lines at the beginning of the file that start with # or % are stored in the history. Each remaining line holds a time, followed by two columns for each mode: the real and imaginary parts if DataFormat contains "ReIm", or the magnitude and argument if it contains "MagArg" (ignoring case). The modes are assumed to be ordered as \((2, -2), (2, -1), \ldots, (2, 2), (3, -3), \ldots\); if they are not, the \((\ell, m)\) data must be corrected with Waveform.SetLM.

Waveform(T, LM, Data)

A waveform with the times T, an array of floats; the mode labels LM, an array of integers with shape (NModes, 2), each row of which holds \(\ell\) and \(m\); and the complex mode data Data, with shape (NModes, NTimes).

Every constructor except the copy constructor sets the spin weight to -2 and the boost weight to -1, and leaves the frame type and the data type unknown.

classmethod __new__(*args, **kwargs)

Frame types and data types

The frame type and the data type of a Waveform are integers, given names by these module-level constants.

GWFrames.UnknownFrameType
GWFrames.Inertial
GWFrames.Coprecessing
GWFrames.Coorbital
GWFrames.Corotating

The frames in which the modes of a Waveform may be decomposed, as returned by Waveform.FrameType and set by Waveform.SetFrameType.

GWFrames.UnknownDataType
GWFrames.h
GWFrames.hdot
GWFrames.Psi4
GWFrames.Psi3
GWFrames.Psi2
GWFrames.Psi1
GWFrames.Psi0

The quantities that a Waveform may hold, as returned by Waveform.DataType and set by Waveform.SetDataType.

Copying, slicing, and interpolating

Waveform.CopyWithoutData() → Waveform

Return a copy of this waveform without its times, frame, modes, or data.

The copy has the spin weight, boost weight, history, version history, frame type, data type, and scaling flags of this waveform, but its times, frame data, \((\ell, m)\) data, and mode data are empty.

Returns:

Waveform – The copy.

Waveform.SliceOfTimeIndices(i_t_a: int, i_t_b: int = 0) → Waveform

Return a copy of the waveform restricted to a range of time indices.

The copy contains the time steps with indices from i_t_a up to, but not including, i_t_b.

Parameters:
  • i_t_a (int) – Index of the first time step to include.

  • i_t_b (int, default 0) – Index one past the last time step to include. If it is 0, only the time step i_t_a is included.

Returns:

Waveform – The slice of the waveform.

Waveform.SliceOfTimeIndicesWithEll2(i_t_a: int, i_t_b: int = 0) → Waveform

Return a copy of the waveform restricted to time indices and \(\ell = 2\).

The copy contains only the five modes with \(\ell = 2\), ordered by \(m\), at the time steps with indices from i_t_a up to, but not including, i_t_b.

Parameters:
  • i_t_a (int) – Index of the first time step to include.

  • i_t_b (int, default 0) – Index one past the last time step to include. If it is 0, only the time step i_t_a is included.

Returns:

Waveform – The slice of the waveform.

Waveform.SliceOfTimeIndicesWithoutModes(i_t_a: int, i_t_b: int = 0) → Waveform

Return a copy of the waveform restricted to time indices, without mode data.

The copy contains the times and frame data at the time steps with indices from i_t_a up to, but not including, i_t_b, but no modes. Frame data with one rotor for each time step are sliced along with the times, and a constant frame (a single rotor) is copied unchanged.

Parameters:
  • i_t_a (int) – Index of the first time step to include.

  • i_t_b (int, default 0) – Index one past the last time step to include. If it is 0, only the time step i_t_a is included.

Returns:

Waveform – The slice of the waveform.

Waveform.SliceOfTimes(t_a: float = -1e+300, t_b: float = 1e+300) → Waveform

Return a copy of the waveform restricted to an interval of time.

The copy begins at the last time step at or before t_a (or at the first time step, if there is none) and ends at the last time step at or before t_b. With the default arguments, the whole waveform is copied.

Parameters:
  • t_a (float, default -1e300) – Beginning of the interval.

  • t_b (float, default 1e300) – End of the interval.

Returns:

Waveform – The slice of the waveform.

Waveform.SliceOfTimesWithEll2(t_a: float = -1e+300, t_b: float = 1e+300) → Waveform

Return a copy of the waveform restricted to a time span and \(\ell = 2\).

The copy contains only the five modes with \(\ell = 2\), ordered by \(m\). It begins at the last time step at or before t_a (or at the first time step, if there is none) and ends at the last time step at or before t_b.

Parameters:
  • t_a (float, default -1e300) – Beginning of the interval.

  • t_b (float, default 1e300) – End of the interval.

Returns:

Waveform – The slice of the waveform.

Waveform.SliceOfTimesWithoutModes(t_a: float = -1e+300, t_b: float = 1e+300) → Waveform

Return a copy of the waveform restricted to a time interval, without modes.

The copy contains the times and frame data, but no modes. It begins at the last time step at or before t_a (or at the first time step, if there is none) and ends at the last time step at or before t_b. Frame data with one rotor for each time step are sliced along with the times, and a constant frame (a single rotor) is copied unchanged.

Parameters:
  • t_a (float, default -1e300) – Beginning of the interval.

  • t_b (float, default 1e300) – End of the interval.

Returns:

Waveform – The slice of the waveform.

Waveform.Interpolate(
NewTime: ndarray,
AllowTimesOutsideCurrentDomain: bool = False,
) → Waveform

Interpolate the waveform to a new set of times.

The real and imaginary parts of each mode are interpolated with cubic splines, and frame data with one rotor for each time step are interpolated with Quaternions.Squad. All other properties, including the spin weight, boost weight, and version history, are copied. This waveform is not changed.

Parameters:
  • NewTime (array_like of float) – New times to which the data are interpolated, in increasing order.

  • AllowTimesOutsideCurrentDomain (bool, default False) – If true, the modes are set to zero at times outside the current time domain, and frame data with one rotor for each time step are held at the rotor at the nearer end of that domain (the first rotor at earlier times, and the last at later times); if false, such times raise an error.

Returns:

Waveform – The interpolated waveform.

Waveform.InterpolateInPlace(NewTime: ndarray) → object

Interpolate the waveform to a new set of times, in place.

The real and imaginary parts of each mode are interpolated with cubic splines, and frame data with one rotor for each time step are interpolated with Quaternions.Squad. Times outside the current time domain raise an error. A single line recording this call is appended to the history.

Parameters:

NewTime (array_like of float) – New times to which the data are interpolated.

Returns:

Waveform – This object, modified in place.

Accessing the data

Waveform.NTimes() → int

Return the number of time steps.

Returns:

int – The number of time steps.

Waveform.NModes() → int

Return the number of modes.

Returns:

int – The number of modes.

Waveform.T() → ndarray
Waveform.T(TimeIndex: int) → float

Return the times of the waveform, or the time at one time step.

Parameters:

TimeIndex (int, optional) – Index of the time step. If omitted, all of the times are returned.

Returns:

float or ndarray of float – The time at TimeIndex, or the array of all times.

Waveform.Frame() → ndarray[Quaternion]
Waveform.Frame(TimeIndex: int) → Quaternion

Return the frame data of the waveform, or the frame at one time step.

The frame data consist of no rotors, of a single rotor for a constant frame, or of one rotor for each time step. When TimeIndex is given for a constant frame, that single rotor is returned; when it is given and there are no rotors, the frame is the identity, and the identity rotor is returned.

Parameters:

TimeIndex (int, optional) – Index of the time step. If omitted, all of the frame data are returned.

Returns:

Quaternion or ndarray of Quaternion – The rotor at TimeIndex, or the array of all frame data.

Waveform.LM() → ndarray
Waveform.LM(Mode: int) → ndarray

Return the \((\ell, m)\) values of the modes, or of one mode.

Parameters:

Mode (int, optional) – Index of the mode. If omitted, the values for all modes are returned.

Returns:

ndarray of int, shape (2,) or (N, 2) – The values \((\ell, m)\) of the mode Mode, or one row of such values for each mode.

Waveform.Data() → ndarray
Waveform.Data(Mode: int) → ndarray
Waveform.Data(Mode: int, TimeIndex: int) → complex

Return the complex mode data.

Parameters:
  • Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

  • TimeIndex (int, optional) – Index of the time step. If omitted, the data at all times are returned. It may be given only together with Mode.

Returns:

complex or ndarray of complex – The data of one mode at one time step; or, if TimeIndex is omitted, the data for that mode at every time; or, if both are omitted, an array of shape (NModes, NTimes).

Waveform.Re() → ndarray
Waveform.Re(Mode: int) → ndarray
Waveform.Re(Mode: int, TimeIndex: int) → float

Return the real parts of the mode data.

Parameters:
  • Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

  • TimeIndex (int, optional) – Index of the time step. If omitted, the data at all times are returned. It may be given only together with Mode.

Returns:

float or ndarray of float – The real part of the data of one mode at one time step; or, if TimeIndex is omitted, the real parts for that mode at every time; or, if both are omitted, an array of shape (NModes, NTimes).

Waveform.Im() → ndarray
Waveform.Im(Mode: int) → ndarray
Waveform.Im(Mode: int, TimeIndex: int) → float

Return the imaginary parts of the mode data.

Parameters:
  • Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

  • TimeIndex (int, optional) – Index of the time step. If omitted, the data at all times are returned. It may be given only together with Mode.

Returns:

float or ndarray of float – The imaginary part of the data of one mode at one time step; or, if TimeIndex is omitted, the imaginary parts for that mode at every time; or, if both are omitted, an array of shape (NModes, NTimes).

Waveform.Abs() → ndarray
Waveform.Abs(Mode: int) → ndarray
Waveform.Abs(Mode: int, TimeIndex: int) → float

Return the absolute values of the mode data.

Parameters:
  • Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

  • TimeIndex (int, optional) – Index of the time step. If omitted, the data at all times are returned. It may be given only together with Mode.

Returns:

float or ndarray of float – The absolute value of the data of one mode at one time step; or, if TimeIndex is omitted, the absolute values for that mode at every time; or, if both are omitted, an array of shape (NModes, NTimes).

Waveform.Arg() → ndarray
Waveform.Arg(Mode: int) → ndarray
Waveform.Arg(Mode: int, TimeIndex: int) → float

Return the arguments (phases) of the mode data.

The arguments are not unwrapped; they lie between \(-\pi\) and \(\pi\). For a continuous phase, use Waveform.ArgUnwrapped.

Parameters:
  • Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

  • TimeIndex (int, optional) – Index of the time step. If omitted, the data at all times are returned. It may be given only together with Mode.

Returns:

float or ndarray of float – The argument of the data of one mode at one time step; or, if TimeIndex is omitted, the arguments for that mode at every time; or, if both are omitted, an array of shape (NModes, NTimes).

Waveform.ArgUnwrapped() → ndarray
Waveform.ArgUnwrapped(Mode: int) → ndarray

Return the unwrapped arguments (phases) of the mode data.

Multiples of \(2\pi\) are added to the arguments of each mode to remove the jumps between \(-\pi\) and \(\pi\), so that the phase is continuous in time.

Parameters:

Mode (int, optional) – Index of the mode. If omitted, the data for all modes are returned.

Returns:

ndarray of float – The unwrapped arguments for the mode Mode at every time, or, if Mode is omitted, an array of shape (NModes, NTimes).

Waveform.SpinWeight() → int

Return the spin weight of the data.

Returns:

int – The spin weight.

Waveform.BoostWeight() → int

Return the boost weight of the data.

Returns:

int – The boost weight.

Waveform.FrameType() → int

Return the frame type of the waveform.

Returns:

int – One of the module constants GWFrames.UnknownFrameType, GWFrames.Inertial, GWFrames.Coprecessing, GWFrames.Coorbital, and GWFrames.Corotating.

Waveform.FrameTypeString() → str

Return the name of the frame type of the waveform.

Returns:

str – The name of the frame type, such as "Inertial" or "Corotating".

Waveform.DataType() → int

Return the data type of the waveform.

Returns:

int – One of the module constants GWFrames.UnknownDataType, GWFrames.h, GWFrames.hdot, GWFrames.Psi4, GWFrames.Psi3, GWFrames.Psi2, GWFrames.Psi1, and GWFrames.Psi0.

Waveform.DataTypeString() → str

Return the name of the data type of the waveform.

Returns:

str – The name of the data type, such as "h" or "Psi4".

Waveform.DataTypeLaTeXString() → str

Return a LaTeX expression for the data type of the waveform.

Returns:

str – The LaTeX expression, such as "\dot{h}" or "\Psi_4".

Waveform.DescriptorString() → str

Return a short description of the data, suitable for a file name.

The description combines the name of the data type with the factors of radius and mass that have been scaled out of the data, as recorded by Waveform.RIsScaledOut and Waveform.MIsScaledOut; examples are "rhOverM", "rMPsi4", and "rhdot".

Returns:

str – The description.

Waveform.GetFileNamePrefix()

Return a prefix for file names describing the data type and frame type.

The prefix is like "rhOverM_Corotating_" or "rMPsi4_Inertial_", and is prepended to file names by Waveform.OutputToH5 and Waveform.OutputToNRAR.

Returns:

str

Waveform.GetLaTeXDataDescription()

Return a LaTeX description of the data, for labeling plots.

The description includes the factors of \(r\) and \(M\) that have been scaled out of the data, as in r\,h/M or r\,M\,\psi_4.

Returns:

str

Waveform.RIsScaledOut() → bool

Return whether the radial dependence has been scaled out of the data.

Returns:

bool – True if the data represent quantities such as \(r h\) or \(r \Psi_4\).

Waveform.MIsScaledOut() → bool

Return whether the mass dependence has been scaled out of the data.

Returns:

bool – True if the data represent quantities such as \(h/M\) or \(M \Psi_4\), and the times represent \(t/M\).

Waveform.HistoryStr() → str

Return the history of the waveform.

The history records the operations applied to the waveform since it was created.

Returns:

str – The history.

Waveform.VersionHist() → list[tuple[str, str]]

Return the version history of the waveform.

Returns:

list of tuple of str – The version history, as a list of pairs of strings.

Changing the data

Waveform.DropTimesOutside(ta: float, tb: float) → object

Remove the data at times outside an interval, in place.

The time steps that remain are those with ta <= t <= tb. If tb is less than ta, or no time step lies in the interval, all time steps are removed. A frame with one rotor per time step is trimmed along with the times, while a constant frame (one rotor, or none) is left unchanged.

Parameters:
  • ta (float) – Beginning of the interval.

  • tb (float) – End of the interval.

Returns:

Waveform – This object, modified in place.

Waveform.DropEllModes(EllModesToDrop: ndarray) → object

Remove the modes with the given values of \(\ell\), in place.

Parameters:

EllModesToDrop (array_like of int) – Values of \(\ell\) whose modes are removed.

Returns:

Waveform – This object, modified in place.

Waveform.KeepOnlyEllModes(EllModesToKeep: ndarray) → object

Remove all modes except those with the given values of \(\ell\), in place.

Parameters:

EllModesToKeep (array_like of int) – Values of \(\ell\) whose modes are kept.

Returns:

Waveform – This object, modified in place.

Waveform.KeepOnlyEll2() → object

Remove all modes except those with \(\ell = 2\), in place.

Returns:

Waveform – This object, modified in place.

Waveform.SetT(a: ndarray) → object

Set the times of the waveform.

The mode data and frame data are not changed, so the number of times should normally equal Waveform.NTimes. This method is identical to Waveform.SetTime.

Parameters:

a (array_like of float) – The new times.

Returns:

Waveform – This object, modified in place.

Waveform.SetTime(a: ndarray) → object

Set the times of the waveform.

The mode data and frame data are not changed, so the number of times should normally equal Waveform.NTimes. This method is identical to Waveform.SetT.

Parameters:

a (array_like of float) – The new times.

Returns:

Waveform – This object, modified in place.

Waveform.SetFrame(a: ndarray[Quaternion]) → object

Set the frame data of the waveform.

The mode data are not changed; to rotate them along with the frame, use Waveform.RotateDecompositionBasis instead.

Parameters:

a (array_like of Quaternion) – Rotors taking the standard basis into the basis with respect to which the modes are decomposed: none, a single rotor for a constant frame, or one rotor for each time step.

Returns:

Waveform – This object, modified in place.

Waveform.SetFrameType(Type: int) → object

Set the frame type of the waveform.

Only the recorded frame type changes; the data are not altered.

Parameters:

Type (int) – One of the module constants GWFrames.UnknownFrameType, GWFrames.Inertial, GWFrames.Coprecessing, GWFrames.Coorbital, and GWFrames.Corotating.

Returns:

Waveform – This object, modified in place.

Waveform.SetDataType(Type: int) → object

Set the data type of the waveform.

Only the recorded data type changes; the data are not altered.

Parameters:

Type (int) – One of the module constants GWFrames.UnknownDataType, GWFrames.h, GWFrames.hdot, GWFrames.Psi4, GWFrames.Psi3, GWFrames.Psi2, GWFrames.Psi1, and GWFrames.Psi0.

Returns:

Waveform – This object, modified in place.

Waveform.SetRIsScaledOut(Scaled: bool) → object

Record whether the radial dependence has been scaled out of the data.

When it has, the data represent quantities such as \(r h\) or \(r \Psi_4\). Only the recorded flag changes; the data are not altered.

Parameters:

Scaled (bool) – True if the radial dependence has been scaled out.

Returns:

Waveform – This object, modified in place.

Waveform.SetMIsScaledOut(Scaled: bool) → object

Record whether the mass dependence has been scaled out of the data.

When it has, the data represent quantities such as \(h/M\) or \(M \Psi_4\), and the times represent \(t/M\). Only the recorded flag changes; the data are not altered.

Parameters:

Scaled (bool) – True if the mass dependence has been scaled out.

Returns:

Waveform – This object, modified in place.

Waveform.SetLM(a: ndarray) → object

Set the \((\ell, m)\) values of the modes.

The mode data are not changed, so the number of rows should normally equal Waveform.NModes.

Parameters:

a (array_like of int, shape (N, 2)) – The new \((\ell, m)\) values, one row for each mode.

Returns:

Waveform – This object, modified in place.

Waveform.SetData(a: ndarray) → object
Waveform.SetData(i_Mode: int, i_Time: int, a: complex | complex | float) → object

Set the mode data of the waveform, either entirely or at one point.

The times and the \((\ell, m)\) data are not changed. When a single value is set, the indices are not checked, so they must lie within the current shape of the data.

Parameters:
  • i_Mode (int, optional) – Index of the mode to set. It must be given together with i_Time.

  • i_Time (int, optional) – Index of the time step to set.

  • a (array_like of complex or complex) – If i_Mode and i_Time are omitted, the complete mode data, with shape (NModes, NTimes), which replace the current data. Otherwise, the single value to store for that mode and time step.

Returns:

Waveform – This object, modified in place.

Waveform.ResizeData(NModes: int, NTimes: int) → object

Change the shape of the array of mode data.

If the shape changes, the existing data are discarded and replaced by zeros. The times and the \((\ell, m)\) data are not changed.

Parameters:
  • NModes (int) – The new number of modes.

  • NTimes (int) – The new number of time steps.

Returns:

Waveform – This object, modified in place.

Waveform.SetSpinWeight(NewSpinWeight: int) → object

Set the spin weight of the data.

Only the recorded spin weight changes; the data are not altered.

Parameters:

NewSpinWeight (int) – The new spin weight.

Returns:

Waveform – This object, modified in place.

Waveform.SetBoostWeight(NewBoostWeight: int) → object

Set the boost weight of the data.

Only the recorded boost weight changes; the data are not altered.

Parameters:

NewBoostWeight (int) – The new boost weight.

Returns:

Waveform – This object, modified in place.

Waveform.AppendHistory(Hist: str) → object

Append text to the history of the waveform.

The text is appended exactly as given; no newline is added.

Parameters:

Hist (str) – Text to append.

Returns:

Waveform – This object, modified in place.

Waveform.SetHistory(Hist: str) → object

Replace the history of the waveform.

Parameters:

Hist (str) – The new history.

Returns:

Waveform – This object, modified in place.

Waveform.SetVersionHist(VerHist: Sequence[tuple[str, str]]) → object

Set the version history of the waveform.

Parameters:

VerHist (list of tuple of str) – The new version history, as a list of pairs of strings, in the form returned by Waveform.VersionHist.

Returns:

Waveform – This object, modified in place.

Waveform.swap(b: Waveform) → None

Exchange the entire contents of this waveform with those of another.

All of the data, including the histories, are exchanged without being copied.

Parameters:

b (Waveform) – The other waveform.

Characterizing the data

Waveform.EllMax() → int

Return the largest value of \(\ell\) present in the data.

Returns:

int – The largest value of \(\ell\).

Waveform.FindModeIndex(L: int, M: int) → int

Return the index of the mode with the given \((\ell, m)\) values.

If no such mode is present, an IndexError is raised.

Parameters:
  • L (int) – The value of \(\ell\).

  • M (int) – The value of \(m\).

Returns:

int – The index of the mode.

Waveform.FindModeIndexWithoutError(L: int, M: int) → int

Return the index of the mode with given \((\ell, m)\), without raising.

Unlike Waveform.FindModeIndex, this method raises no error when the mode is missing; instead, it returns NModes() + 1, which is not a valid index.

Parameters:
  • L (int) – The value of \(\ell\).

  • M (int) – The value of \(m\).

Returns:

int – The index of the mode, or NModes() + 1 if it is not present.

Waveform.DataDot(Mode: int) → ndarray

Return the time derivative of the data of one mode.

The derivative is computed with a fourth-order finite-difference formula for nonuniformly spaced times. Only the mode data are differentiated; the time dependence of a rotating frame is not taken into account.

Parameters:

Mode (int) – Index of the mode.

Returns:

ndarray of complex – The derivative at each time step.

Waveform.Differentiate() → object

Differentiate the waveform with respect to time, in place.

Each mode is differentiated as in Waveform.DataDot. The waveform must be in the inertial frame; for any other frame type, a NotImplementedError is raised. The boost weight is reduced by one, and the data type changes from h to hdot, or from hdot to Psi4; any other data type becomes UnknownDataType.

Returns:

Waveform – This object, modified in place.

Waveform.Norm(TakeSquareRoot: bool = False) → ndarray

Return the norm of the waveform at each time.

The norm is the sum over all modes of the squared magnitudes of the data, \(\sum_{\ell,m} \lvert f^{\ell,m} \rvert^2\); it is called a norm in analogy with std::norm for complex numbers in C++, which is the square of the absolute value. Optionally, the square root is taken, giving the usual \(L^2\) norm of the waveform.

Parameters:

TakeSquareRoot (bool, default False) – If true, the square root is taken at each time.

Returns:

ndarray of float – The norm at each time step.

Waveform.MaxNormIndex(SkipFraction: int = 4) → int

Return the index of the time step at which the norm is largest.

The search for the maximum of Waveform.Norm begins at the time step with index NTimes() // SkipFraction, so that junk radiation near the beginning of the data is skipped. With SkipFraction = NTimes() + 1, all of the data are searched.

Parameters:

SkipFraction (int, default 4) – Inverse of the fraction of the data to skip before searching.

Returns:

int – The index of the time step with the largest norm.

Waveform.MaxNormTime(SkipFraction: int = 4) → float

Return the time at which the norm is largest.

This is the time at the index returned by Waveform.MaxNormIndex, whose documentation describes SkipFraction.

Parameters:

SkipFraction (int, default 4) – Inverse of the fraction of the data to skip before searching.

Returns:

float – The time with the largest norm.

Rotations and frames

Waveform.RotatePhysicalSystem(R_phys: Quaternion) → object
Waveform.RotatePhysicalSystem(R_phys: ndarray[Quaternion]) → object

Rotate the physical content of the waveform, in place.

The physical system is rotated by R_phys, while the basis with respect to which the modes are decomposed is left in place. The modes are transformed accordingly, and the frame data are multiplied on the right by \(\bar{R}_{\mathrm{phys}}\), so that the frame data record the total rotation. The frame type is not changed.

Parameters:

R_phys (Quaternion or array_like of Quaternion) – Rotor by which to rotate the system, or one rotor for each time step.

Returns:

Waveform – This object, modified in place.

Waveform.RotateDecompositionBasis(R_frame: Quaternion) → object
Waveform.RotateDecompositionBasis(R_frame: ndarray[Quaternion]) → object

Rotate the basis in which the modes are decomposed, in place.

The basis is rotated by R_frame, while the physical system is left in place. The modes are transformed accordingly, and the frame data are multiplied on the right by R_frame, so that they record the total rotation of the basis. The frame type is not changed.

Parameters:

R_frame (Quaternion or array_like of Quaternion) – Rotor by which to rotate the basis, or one rotor for each time step. If an empty array is given, nothing is done.

Returns:

Waveform – This object, modified in place.

Waveform.LdtVector(Lmodes: ndarray = []) → ndarray

Return the vector \(\langle L \partial_t \rangle\) at each time.

This quantity, defined in “Angular velocity of gravitational radiation from precessing binaries and the corotating frame” (https://arxiv.org/abs/1302.2919), is

\[\langle L \partial_t \rangle^a = \sum_{\ell,m,m'} \Im \left[ \bar{f}^{\ell,m'} \langle \ell,m' | L_a | \ell,m \rangle \dot{f}^{\ell,m} \right].\]

The vector is given with respect to the (possibly rotating) mode frame \((X, Y, Z)\), rather than the inertial frame \((x, y, z)\).

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float, shape (N, 3) – The vector, one row for each time step.

Waveform.LLMatrix(Lmodes: ndarray = []) → list[Matrix]

Return the matrix \(\langle LL \rangle\) at each time.

This quantity, defined in “Angular velocity of gravitational radiation from precessing binaries and the corotating frame” (https://arxiv.org/abs/1302.2919), is

\[\langle LL \rangle^{ab} = \sum_{\ell,m,m'} \bar{f}^{\ell,m'} \langle \ell,m' | L_a L_b | \ell,m \rangle f^{\ell,m}.\]

The matrix is given with respect to the (possibly rotating) mode frame \((X, Y, Z)\), rather than the inertial frame \((x, y, z)\).

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

list of Matrix – The 3-by-3 matrix at each time step.

Waveform.LLDominantEigenvector(
Lmodes: ndarray = [],
RoughInitialEllDirection: Quaternion = Quaternion(0, 0, 0, 1),
) → ndarray

Return the dominant eigenvector of \(\langle LL \rangle\) at each time.

This is the principal axis of Waveform.LLMatrix, as prescribed by O’Shaughnessy et al. (2011). The eigenvectors are normalized, and their signs are chosen so that they vary continuously in time, with the first one more nearly parallel than antiparallel to RoughInitialEllDirection. For a post-Newtonian system, the orbital angular-velocity direction is a good guess for that direction; the default, the z axis, is usually correct.

The vectors are given with respect to the (possibly rotating) mode frame \((X, Y, Z)\), rather than the inertial frame \((x, y, z)\).

Parameters:
  • Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

  • RoughInitialEllDirection (Quaternion, default Quaternions.zHat) – Rough guess at the direction of the eigenvector at the first time step.

Returns:

ndarray of float, shape (N, 3) – The unit eigenvector, one row for each time step.

Waveform.AngularVelocityVector(Lmodes: ndarray = []) → ndarray

Return the angular velocity of the waveform at each time.

This is the angular velocity defined in Sec. II of “Angular velocity of gravitational radiation from precessing binaries and the corotating frame” (https://arxiv.org/abs/1302.2919), found by solving \(\langle LL \rangle \vec{\omega} = -\langle L \partial_t \rangle\) at each time step (see Waveform.LLMatrix and Waveform.LdtVector). The vector is given with respect to the (possibly rotating) mode frame \((X, Y, Z)\), rather than the inertial frame \((x, y, z)\); for the latter, use Waveform.AngularVelocityVectorRelativeToInertial.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sums. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float, shape (N, 3) – The angular velocity, one row for each time step.

Waveform.AngularVelocityVectorRelativeToInertial(Lmodes: ndarray = []) → ndarray

Return the angular velocity of the waveform relative to the inertial frame.

This is the angular velocity defined in Sec. II of “Angular velocity of gravitational radiation from precessing binaries and the corotating frame” (https://arxiv.org/abs/1302.2919). Unlike most methods of Waveform, this one gives the vector with respect to the inertial frame \((x, y, z)\), rather than the (possibly rotating) mode frame \((X, Y, Z)\): the result of Waveform.AngularVelocityVector is rotated by the frame, and the angular velocity of a time-dependent frame is added.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sums. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float, shape (N, 3) – The angular velocity, one row for each time step.

Waveform.CorotatingFrame(Lmodes: ndarray = []) → ndarray[Quaternion]

Return the corotating frame of the waveform.

The corotating frame is the frame whose angular velocity is the angular velocity of the waveform, as returned by Waveform.AngularVelocityVector; it is found with Quaternions.FrameFromAngularVelocity. The rotors are given relative to the (possibly rotating) mode frame \((X, Y, Z)\), rather than the inertial frame \((x, y, z)\).

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sums. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of Quaternion – The rotor of the corotating frame at each time step.

Waveform.TransformToCoprecessingFrame(Lmodes: ndarray = []) → object

Transform the waveform to the coprecessing frame, in place.

In the coprecessing frame, the z axis is aligned with the dominant eigenvector of \(\langle LL \rangle\) (the vector \(V_h\) of O’Shaughnessy et al. 2011; see Waveform.LLDominantEigenvector), and the rotation about the z axis satisfies the minimal-rotation condition of Boyle, Owen, and Pfeiffer (2011). The frame type is set to Coprecessing.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

Waveform – This object, modified in place.

Waveform.TransformToAngularVelocityFrame(Lmodes: ndarray = []) → object

Transform the waveform to the frame aligned with its angular velocity.

In this frame, the z axis is aligned with the angular-velocity vector of Waveform.AngularVelocityVector, and the rotation about the z axis satisfies the minimal-rotation condition. Note that this is not the corotating frame. The frame type is set to Coprecessing. The transformation is done in place.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sums. If empty or omitted, all \(\ell\) values are used.

Returns:

Waveform – This object, modified in place.

Waveform.TransformToCorotatingFrame(Lmodes: ndarray = []) → object

Transform the waveform to the corotating frame, in place.

The decomposition basis is rotated by the rotors of Waveform.CorotatingFrame, and the frame type is set to Corotating. This leaves a constant of integration unset; it may be fixed by aligning the frame to the modes, for example with Waveform.AlignDecompositionFrameToModes.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sums. If empty or omitted, all \(\ell\) values are used.

Returns:

Waveform – This object, modified in place.

Waveform.TransformToInertialFrame() → object

Transform the waveform to the inertial frame, in place.

The stored frame data are used to transform from whatever rotating frame the waveform is in to a stationary, inertial frame. This is the usual frame at future null infinity, in which gravitational-wave observations are made. After the transformation, the frame data are empty and the frame type is Inertial.

If the frame type is already Inertial or is UnknownFrameType, or if there are no frame data, a warning is printed and nothing is done. Otherwise, there must be one rotor for each time step.

Returns:

Waveform – This object, modified in place.

Alignment, comparison, and hybridization

Waveform.GetAlignmentsOfDecompositionFrameToModes(
Lmodes: ndarray = [],
) → ndarray[Quaternion]

Return the rotors aligning the decomposition frame to the modes at each time.

At each time step, this finds the rotor \(R_{\varepsilon}\) by which the decomposition basis would be rotated to align it with the waveform, as in Waveform.AlignDecompositionFrameToModes. Computing the rotors at every time step at once is useful when many such alignments must be tried, because interpolation is slow. Unlike similar methods, this one does not use an approximate direction of \(\hat{n}\) to choose the direction of the X axis.

The waveform must be in the coprecessing, coorbital, or corotating frame, with one frame rotor for each time step.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to use in computing \(\langle LL \rangle\). If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of Quaternion – The rotor \(R_{\varepsilon}\) at each time step.

Waveform.GetAlignmentOfDecompositionFrameToModes(
t_fid: float,
nHat_t_fid: Quaternion = Quaternion(0, 1, 0, 0),
Lmodes: ndarray = [],
) → Quaternion

Return the rotor aligning the decomposition frame to the modes at one time.

This finds the rotor \(R_{\varepsilon}\) that Waveform.AlignDecompositionFrameToModes applies, without applying it; see that method for details. The waveform must be in the coprecessing, coorbital, or corotating frame, and t_fid must lie within its times.

Parameters:
  • t_fid (float) – Fiducial time at which the alignment is done.

  • nHat_t_fid (Quaternion, default Quaternions.xHat) – Approximate direction of \(\hat{n}\) (the vector from one black hole to the other) at t_fid, which sets the direction of the X axis.

  • Lmodes (array_like of int, optional) – Values of \(\ell\) to use in computing \(\langle LL \rangle\). If empty or omitted, all \(\ell\) values are used.

Returns:

Quaternion – The rotor \(R_{\varepsilon}\).

Waveform.AlignDecompositionFrameToModes(
t_fid: float,
nHat_t_fid: Quaternion = Quaternion(0, 1, 0, 0),
Lmodes: ndarray = [],
) → object

Fix the orientation of the corotating frame by aligning it to the modes.

The corotating frame is defined only up to a constant rotor \(R_{\varepsilon}\): if \(R_{\mathrm{corot}}\) is corotating, then so is \(R_{\mathrm{corot}} R_{\varepsilon}\). This method uses that freedom to align the frame with the modes at the fiducial time t_fid. The Z axis of the decomposition basis is placed along the dominant eigenvector of \(\langle LL \rangle\) (as suggested by O’Shaughnessy et al.), with its sign chosen to be closer to the angular velocity than not; the rotation about that axis is fixed by the phases of the \((2, \pm 2)\) modes; and the remaining choice of sign of the X axis is made so that X lies closer to nHat_t_fid than not. The decomposition basis is then rotated by \(R_{\varepsilon}\).

The waveform must be in the coprecessing, coorbital, or corotating frame, and t_fid must lie within its times.

Parameters:
  • t_fid (float) – Fiducial time at which the alignment is done.

  • nHat_t_fid (Quaternion, default Quaternions.xHat) – Approximate direction of \(\hat{n}\) (the vector from one black hole to the other) at t_fid.

  • Lmodes (array_like of int, optional) – Values of \(\ell\) to use in computing \(\langle LL \rangle\). If empty or omitted, all \(\ell\) values are used.

Returns:

Waveform – This object, modified in place.

Waveform.Compare(
B: Waveform,
MinTimeStep: float = 0.005,
MinTime: float = -3e+300,
) → Waveform

Return the difference between another waveform and this one.

The mode data of the result are the data of B minus the data of this waveform, both interpolated with cubic splines to the times common to the two (as found by Intersection). The frame of the result is the rotation taking the frame of this waveform into the frame of B. The data are compared as complex numbers, rather than as moduli and phases. A warning is printed if the two waveforms have different frame types.

Parameters:
  • B (Waveform) – The waveform to compare with this one.

  • MinTimeStep (float, default 0.005) – Lower limit on the time step of the result.

  • MinTime (float, default -3.0e300) – Earliest time of the result. The result begins at the earliest time common to the two waveforms, or at MinTime, whichever is later.

Returns:

Waveform – The difference.

Waveform.Hybridize(
B: Waveform,
t1: float,
t2: float,
tMinStep: float = 0.005,
) → Waveform

Return a hybrid of this waveform and another.

The result has exactly the data of this waveform before t1 and exactly the data of B after t2, with a smooth (\(C^\infty\)) blend between the two in the interval from t1 to t2; the frame data are blended in the same way. The waveforms are not aligned first; that must already have been done (for example, with AlignWaveforms). Both waveforms must have data throughout the transition interval. This waveform is not changed.

Parameters:
  • B (Waveform) – The waveform with which to hybridize this one.

  • t1 (float) – Beginning of the transition interval.

  • t2 (float) – End of the transition interval.

  • tMinStep (float, default 0.005) – Lower limit on the time step of the result.

Returns:

Waveform – The hybrid waveform.

GWFrames.AlignWaveforms(
A: Waveform,
B: Waveform,
t_1: float,
t_2: float,
InitialEvaluations: int = 0,
nHat_A: ndarray = [],
Debug: bool = False,
) → None

Align two waveforms in time and orientation, in place.

If either waveform is in the inertial frame, it is first transformed to its corotating frame; otherwise, it must already be in the corotating frame (the coorbital frame, for example, raises an error). The frame of each waveform is then aligned to its modes at the time t_mid = (t_1 + t_2) / 2, as in Waveform.AlignDecompositionFrameToModes. Finally, B is shifted in time and rotated by a constant rotor so that it matches A as closely as possible over the interval from t_1 to t_2; during this optimization, the alignment of the frame of B to its modes is adjusted to account for the changing meaning of t_mid.

The times t_1 and t_2 refer to the time axis of A. The algorithm assumes that the waveforms are already reasonably well aligned in time. In particular, the final value of t_mid + deltat for B must lie somewhere in the interval from t_1 to t_2, and after the time shift, B must have data over all of that interval. The initial, coarse search considers time shifts of at most (t_2 - t_1) / 2 in either direction, further limited so that the shifted interval stays at least one time step inside the data of B.

As long as this last condition is satisfied, and the waveforms are even remotely well sampled, and assuming the code’s logic does not fail due to otherwise weird or unexpected inputs, I (Mike Boyle) do hereby guarantee that this algorithm will find the optimal alignment in both time and attitude. Or your money back.

Parameters:
  • A (Waveform) – The fixed waveform. Its frame is aligned to its modes, but it is not shifted in time.

  • B (Waveform) – The adjusted waveform. Its frame is aligned to its modes, and it is shifted in time and rotated.

  • t_1 (float) – Beginning of the alignment interval.

  • t_2 (float) – End of the alignment interval.

  • InitialEvaluations (int, default 0) – Number of time offsets at which the objective function is evaluated in the initial, coarse optimization. If it is 0, or is not smaller than the number of available time steps of B, every one of those time steps is used.

  • nHat_A (array_like of float, shape (3,), optional) – Approximate direction of \(\hat{n}\) (the vector from black hole A to black hole B) in A at t_mid, which sets the direction of the x axis of the rotating frame. If empty or omitted, the x axis is used.

  • Debug (bool, default False) – If true, intermediate values of the objective function are written to the files XiIntegral.dat and UpsilonIntegral.dat in the current directory.

Symmetries and parity

Waveform.NormalizedAntisymmetry(LModesForAsymmetry: ndarray = []) → ndarray

Return the normalized antisymmetry of the waveform at each time.

This is the quantity \(a\) defined by Boyle et al. (2014): the difference between the field at a point and the complex conjugate of the field at the antipodal point, squared and integrated over the sphere, normalized by the Waveform.Norm of the waveform (its total power at each instant), and with the square root taken. In terms of the modes,

\[a = \sqrt{\frac{\sum_{\ell,m} \lvert f^{\ell,m} - (-1)^{\ell+m} \bar{f}^{\ell,-m} \rvert^2}{4 \sum_{\ell,m} \lvert f^{\ell,m} \rvert^2}}.\]
Parameters:

LModesForAsymmetry (array_like of int, optional) – Values of \(\ell\) to include in the numerator. If empty or omitted, all \(\ell\) values are used. All modes are always used in the denominator.

Returns:

ndarray of float – The normalized antisymmetry at each time step.

Notes

Any mode missing from the data, such as the \((\ell, -m)\) partner of a mode that is present, is treated as zero.

Waveform.DipoleMoment(ellMax: int = 0) → ndarray

Return the dipole moment of the magnitude of the waveform at each time.

The dipole moment is \(\vec{d} = \int \hat{n} \lvert f \rvert^2 \, d\Omega\). Up to a geometric factor, the dipole moment of \(\dot{h}\) is the rate at which momentum is emitted in gravitational waves.

Parameters:

ellMax (int, default 0) – Largest value of \(\ell\) to include. If it is 0, all modes up to Waveform.EllMax are used.

Returns:

ndarray of float, shape (N, 3) – The dipole moment, one row for each time step.

Waveform.MinimalParityViolation() → ndarray

Return the z-parity violation at each time, minimized over orientations.

At each time step, the decomposition basis is rotated so as to minimize the violation of invariance under z parity (reflection across the x-y plane), as measured by Waveform.ZParityViolationNormalized, and the minimum value is returned. The minimization is started from three different orientations, and the smallest result is used. Nonprecessing systems in a suitable frame should have zero violation; precessing systems in any frame, and nonprecessing systems in the wrong frame, show violations.

This method is slow, and it prints its progress to standard error.

Returns:

ndarray of float – The minimal normalized violation at each time step.

Waveform.XParityInvolution() → Waveform

Return the image of the waveform under x parity.

The x-parity operation reflects the x axis, \(x \to -x\), and takes the complex conjugate. In terms of the modes, it maps \(f^{\ell,m}\) to \((-1)^m \bar{f}^{\ell,m}\). The frame rotors are transformed with Quaternions.XParityConjugateSpinor. Every mode up to Waveform.EllMax must be present. This waveform is not changed.

Returns:

Waveform – The transformed waveform.

Waveform.XParitySymmetricPart() → Waveform

Return the part of the waveform that is symmetric under x parity.

This is \((f + P_x f)/2\), where \(P_x f\) is the image of the waveform under x parity, as returned by Waveform.XParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the x axis, the reflection is therefore that of the x axis of the waveform’s own frame, not of the inertial x axis. This waveform is not changed.

Returns:

Waveform – The symmetric part.

Waveform.XParityAntisymmetricPart() → Waveform

Return the part of the waveform that is antisymmetric under x parity.

This is \((f - P_x f)/2\), where \(P_x f\) is the image of the waveform under x parity, as returned by Waveform.XParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the x axis, the reflection is therefore that of the x axis of the waveform’s own frame, not of the inertial x axis. This waveform is not changed.

Returns:

Waveform – The antisymmetric part.

Waveform.XParityViolationSquared(Lmodes: ndarray = []) → ndarray

Return the squared violation of x-parity symmetry at each time.

This is the sum over modes of the squared magnitude of the antisymmetric part (see Waveform.XParityAntisymmetricPart),

\[\sum_{\ell,m} \frac{1}{4} \lvert f^{\ell,m} - (-1)^m \bar{f}^{\ell,m} \rvert^2.\]
Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The squared violation at each time step.

Waveform.XParityViolationNormalized(Lmodes: ndarray = []) → ndarray

Return the normalized violation of x-parity symmetry at each time.

This is the square root of the ratio of Waveform.XParityViolationSquared to Waveform.Norm. The norm always includes all modes.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the violation. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The normalized violation at each time step.

Waveform.YParityInvolution() → Waveform

Return the image of the waveform under y parity.

The y-parity operation reflects the y axis, \(y \to -y\), and takes the complex conjugate. In terms of the modes, it maps \(f^{\ell,m}\) to \(\bar{f}^{\ell,m}\). The frame rotors are transformed with Quaternions.YParityConjugateSpinor. Every mode up to Waveform.EllMax must be present. This waveform is not changed.

Returns:

Waveform – The transformed waveform.

Waveform.YParitySymmetricPart() → Waveform

Return the part of the waveform that is symmetric under y parity.

This is \((f + P_y f)/2\), where \(P_y f\) is the image of the waveform under y parity, as returned by Waveform.YParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the y axis, the reflection is therefore that of the y axis of the waveform’s own frame, not of the inertial y axis. This waveform is not changed.

Returns:

Waveform – The symmetric part.

Waveform.YParityAntisymmetricPart() → Waveform

Return the part of the waveform that is antisymmetric under y parity.

This is \((f - P_y f)/2\), where \(P_y f\) is the image of the waveform under y parity, as returned by Waveform.YParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the y axis, the reflection is therefore that of the y axis of the waveform’s own frame, not of the inertial y axis. This waveform is not changed.

Returns:

Waveform – The antisymmetric part.

Waveform.YParityViolationSquared(Lmodes: ndarray = []) → ndarray

Return the squared violation of y-parity symmetry at each time.

This is the sum over modes of the squared magnitude of the antisymmetric part (see Waveform.YParityAntisymmetricPart),

\[\sum_{\ell,m} \frac{1}{4} \lvert f^{\ell,m} - \bar{f}^{\ell,m} \rvert^2.\]
Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The squared violation at each time step.

Waveform.YParityViolationNormalized(Lmodes: ndarray = []) → ndarray

Return the normalized violation of y-parity symmetry at each time.

This is the square root of the ratio of Waveform.YParityViolationSquared to Waveform.Norm. The norm always includes all modes.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the violation. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The normalized violation at each time step.

Waveform.ZParityInvolution() → Waveform

Return the image of the waveform under z parity.

The z-parity operation reflects the z axis, \(z \to -z\), and takes the complex conjugate. In terms of the modes, it maps \(f^{\ell,m}\) to \((-1)^\ell \bar{f}^{\ell,-m}\). The frame rotors are transformed with Quaternions.ZParityConjugateSpinor. Every mode up to Waveform.EllMax must be present. This waveform is not changed.

Returns:

Waveform – The transformed waveform.

Waveform.ZParitySymmetricPart() → Waveform

Return the part of the waveform that is symmetric under z parity.

This is \((f + P_z f)/2\), where \(P_z f\) is the image of the waveform under z parity, as returned by Waveform.ZParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the z axis, the reflection is therefore that of the z axis of the waveform’s own frame, not of the inertial z axis. This waveform is not changed.

Returns:

Waveform – The symmetric part.

Waveform.ZParityAntisymmetricPart() → Waveform

Return the part of the waveform that is antisymmetric under z parity.

This is \((f - P_z f)/2\), where \(P_z f\) is the image of the waveform under z parity, as returned by Waveform.ZParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, just as a sum of waveforms keeps the frame of its first operand. Unless every frame rotor is a rotation about the z axis, the reflection is therefore that of the z axis of the waveform’s own frame, not of the inertial z axis. This waveform is not changed.

Returns:

Waveform – The antisymmetric part.

Waveform.ZParityViolationSquared(Lmodes: ndarray = []) → ndarray

Return the squared violation of z-parity symmetry at each time.

This is the sum over modes of the squared magnitude of the antisymmetric part (see Waveform.ZParityAntisymmetricPart),

\[\sum_{\ell,m} \frac{1}{4} \lvert f^{\ell,m} - (-1)^\ell \bar{f}^{\ell,-m} \rvert^2.\]
Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The squared violation at each time step.

Waveform.ZParityViolationNormalized(Lmodes: ndarray = []) → ndarray

Return the normalized violation of z-parity symmetry at each time.

This is the square root of the ratio of Waveform.ZParityViolationSquared to Waveform.Norm. The norm always includes all modes.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the violation. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The normalized violation at each time step.

Waveform.ParityInvolution() → Waveform

Return the image of the waveform under parity.

The parity operation inverts all three axes, \(\vec{x} \to -\vec{x}\), and takes the complex conjugate. In terms of the modes, it maps \(f^{\ell,m}\) to \((-1)^{\ell+m} \bar{f}^{\ell,-m}\). The frame rotors are transformed with Quaternions.ParityConjugateSpinor, which leaves them unchanged. Every mode up to Waveform.EllMax must be present. This waveform is not changed. The result is the same as that of Waveform.ConjugateAntipodalEvaluation.

Returns:

Waveform – The transformed waveform.

Waveform.ParitySymmetricPart() → Waveform

Return the part of the waveform that is symmetric under parity.

This is \((f + P f)/2\), where \(P f\) is the image of the waveform under parity, as returned by Waveform.ParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, which parity leaves unchanged. This waveform is not changed.

Returns:

Waveform – The symmetric part.

Waveform.ParityAntisymmetricPart() → Waveform

Return the part of the waveform that is antisymmetric under parity.

This is \((f - P f)/2\), where \(P f\) is the image of the waveform under parity, as returned by Waveform.ParityInvolution. The modes are combined index by index, and the result keeps the frame rotors of this waveform, which parity leaves unchanged. This waveform is not changed.

Returns:

Waveform – The antisymmetric part.

Waveform.ParityViolationSquared(Lmodes: ndarray = []) → ndarray

Return the squared violation of parity symmetry at each time.

This is the sum over modes of the squared magnitude of the antisymmetric part (see Waveform.ParityAntisymmetricPart),

\[\sum_{\ell,m} \frac{1}{4} \lvert f^{\ell,m} - (-1)^{\ell+m} \bar{f}^{\ell,-m} \rvert^2.\]
Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the sum. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The squared violation at each time step.

Waveform.ParityViolationNormalized(Lmodes: ndarray = []) → ndarray

Return the normalized violation of parity symmetry at each time.

This is the square root of the ratio of Waveform.ParityViolationSquared to Waveform.Norm. The norm always includes all modes.

Parameters:

Lmodes (array_like of int, optional) – Values of \(\ell\) to include in the violation. If empty or omitted, all \(\ell\) values are used.

Returns:

ndarray of float – The normalized violation at each time step.

Waveform.ConjugateAntipodalEvaluation() → Waveform

Return the complex conjugate of the waveform at the antipodal point.

The result is the field \(\bar{f}(-\hat{n})\). In terms of the modes, it maps \(f^{\ell,m}\) to \((-1)^{\ell+m} \bar{f}^{\ell,-m}\). This is the same as Waveform.ParityInvolution. This waveform is not changed.

Returns:

Waveform – The transformed waveform.

Waveform.ConjugateAntipodalSymmetricPart() → Waveform

Return the conjugate-antipodal symmetric part of the waveform.

This is \([f(\hat{n}) + \bar{f}(-\hat{n})]/2\), where \(\bar{f}(-\hat{n})\) is returned by Waveform.ConjugateAntipodalEvaluation. This is the same as Waveform.ParitySymmetricPart. This waveform is not changed.

Returns:

Waveform – The symmetric part.

Waveform.ConjugateAntipodalAntisymmetricPart() → Waveform

Return the conjugate-antipodal antisymmetric part of the waveform.

This is \([f(\hat{n}) - \bar{f}(-\hat{n})]/2\), where \(\bar{f}(-\hat{n})\) is returned by Waveform.ConjugateAntipodalEvaluation. This is the same as Waveform.ParityAntisymmetricPart. This waveform is not changed.

Returns:

Waveform – The antisymmetric part.

Evaluation on the sphere, translations, and boosts

Waveform.EvaluateAtPoint(
vartheta: float,
varphi: float,
i_0: int = 0,
i_1: int = -1,
) → ndarray

Evaluate the waveform at a point on the sphere.

The mode data are summed with the spin-weighted spherical harmonics at the given point, taking the frame data into account, so that the angles are measured with respect to the inertial frame. A warning is printed if the frame type is UnknownFrameType.

Parameters:
  • vartheta (float) – Polar angle of the point.

  • varphi (float) – Azimuthal angle of the point.

  • i_0 (int, default 0) – Index of the first time step at which to evaluate.

  • i_1 (int, default -1) – Index one past the last time step at which to evaluate. If it is -1, the waveform is evaluated through the last time step.

Returns:

ndarray of complex – The value of the waveform at each time step from i_0 up to, but not including, i_1.

Waveform.InterpolateToPoint(vartheta: float, varphi: float, t_i: float) → complex

Evaluate the waveform at a point on the sphere and an instant of time.

The waveform is evaluated at the point, as in Waveform.EvaluateAtPoint, at the four time steps nearest t_i, and the result is interpolated in time with a cubic spline. The waveform must have at least four time steps, and t_i must lie within its times.

Parameters:
  • vartheta (float) – Polar angle of the point.

  • varphi (float) – Azimuthal angle of the point.

  • t_i (float) – Time at which to evaluate.

Returns:

complex – The value of the waveform.

Waveform.Translate(deltax: ndarray) → Waveform

Return the waveform translated in space by a time-dependent displacement.

At each time \(t\) and direction \(\hat{n}\), the field of the result is the field of this waveform at the time \(t - \hat{n} \cdot \delta \vec{x}(t)\). The result is decomposed into modes again, and it contains only the times at which data are available in every direction. The displacement is given relative to the inertial frame. This waveform may be in any frame, and need not be transformed first; the result is always in the inertial frame, without frame data. This waveform is not changed.

This method is slow, because it interpolates the waveform to many points at each time step.

Parameters:

deltax (array_like of float, shape (N, 3)) – The displacement at each time step.

Returns:

Waveform – The translated waveform.

Waveform.BoostPsi4(v: ndarray) → object

Apply a boost to \(\Psi_4\) data, in place.

This method does three things at each time step. First, it evaluates the waveform on what will become an equiangular grid after transformation by the boost. Second, at each point of that grid, it combines the present value of \(\Psi_4\) and its conjugate to give the value of \(\Psi_4\) observed in the boosted frame. Finally, it decomposes the result into modes using the new equiangular grid. Time steps with negligible velocity are left unchanged.

Parameters:

v (array_like of float, shape (N, 3)) – The three-velocity of the boosted frame relative to the present frame, at each time step.

Returns:

Waveform – This object, modified in place.

Waveform.BoostHFaked(v: ndarray) → object

Apply an approximate boost to \(h\) data, in place.

This method does three things at each time step. First, it evaluates the waveform on what will become an equiangular grid after transformation by the boost. Second, at each point of that grid, it combines the present value of \(h\) and its conjugate to give the value of \(h\) observed in the boosted frame. Finally, it decomposes the result into modes using the new equiangular grid. Time steps with negligible velocity are left unchanged.

The transformation is that of \(\Psi_4\), multiplied at each point by the appropriate power (-2) of the Lorentz factor. This assumes that \(\ddot{h} = \Psi_4\) in both frames, which need not be true; hence “Faked” in the name of this method, which prints a warning to that effect.

Parameters:

v (array_like of float, shape (N, 3)) – The three-velocity of the boosted frame relative to the present frame, at each time step.

Returns:

Waveform – This object, modified in place.

Arithmetic

Two waveforms with the same times, modes, frames, and types can be added, subtracted, multiplied, and divided mode by mode with the usual operators, and a waveform can be multiplied or divided by a number.

Input and output

Waveform.Output(FileName: str, precision: int = 14) → object

Write the waveform to a text file.

The file begins with the history of the waveform and a header naming the columns. Each following line holds a time, followed by the real and imaginary parts of each mode. Such a file can be read by the constructor Waveform(FileName, "ReIm") if its modes are in the order that the constructor assumes.

Parameters:
  • FileName (str) – Path of the file to write.

  • precision (int, default 14) – Number of significant digits written.

Returns:

Waveform – This object, unchanged.

Waveform.OutputToH5(FileName, FileWriteMode='w')

Write the Waveform to an HDF5 file in the GWFrames format.

This format stores all of the information in the Waveform, including its history, frame, and types, and can be read back with ReadFromH5. It is not compatible with the NRAR format written by OutputToNRAR.

Parameters:
  • FileName (str) – Name of the file to write. The descriptive prefix returned by Waveform.GetFileNamePrefix, such as "rhOverM_Corotating_", is prepended to the base name of the file.

  • FileWriteMode (str, default "w") – Mode in which the file is opened by h5py.File.

Waveform.OutputToNRAR(FileName, FileWriteMode='w')

Write the Waveform to an HDF5 file in the NRAR format.

The NRAR format stores each mode as a dataset of time, real part, and imaginary part, but does not store the frame or the other information that OutputToH5 writes. The data can be read back with ReadFromNRAR.

Parameters:
  • FileName (str) – Name of the file to write. The descriptive prefix returned by Waveform.GetFileNamePrefix, such as "rhOverM_Corotating_", is prepended to the base name of the file. If the name continues after ".h5", as in "Data.h5/Group", the data are written to that group within the file.

  • FileWriteMode (str, default "w") – Mode in which the file is opened by h5py.File.

GWFrames.ReadFromH5(FileName)

Read a Waveform from an HDF5 file in the GWFrames format.

The file should have been written by Waveform.OutputToH5.

Parameters:

FileName (str) – Name of the file to read.

Returns:

Waveform

GWFrames.ReadFromNRAR(FileName)

Read a Waveform from an HDF5 file in the NRAR format.

If the file does not record the frame type, data type, and scaling of the data, defaults are assumed (an inertial frame, with \(r\) and \(M\) scaled out), and the data type is guessed from the file name. The times are made strictly increasing with MonotonicIndices.

Parameters:

FileName (str) – Name of the file to read. If the name continues after ".h5", as in "Data.h5/Group", the data are read from that group within the file.

Returns:

Waveform

GWFrames.MonotonicIndices(T, MinTimeStep=1e-05)

Return the indices that make an array of times strictly increasing.

Whenever a time is not greater than the previous one by more than MinTimeStep, the earlier times that are not less than it (to within MinTimeStep) are dropped. This happens, for example, when a simulation is restarted from an earlier time.

Parameters:
  • T (array_like of float) – The times.

  • MinTimeStep (float, default 1e-5) – The smallest allowed increase between successive times.

Returns:

ndarray of int – Indices into T of the times to keep.