hybrid_jp.analysis.ffts module#

hybrid_jp.analysis.ffts.frame_power(cs: CenteredShock, chunk: int, t_idx: int, subdivisions: int, n_bins: int, centres: bool = True) tuple[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]][source]#

Get the power spectrum of a frame.

Parameters:
  • cs (CenteredShock) – CenteredShock object.

  • chunk (int) – Chunk number.

  • t_idx (int) – Time index.

  • subdivisions (int) – Number of subdivisions in each dimension.

  • n_bins (int) – Number of radial bins.

  • centres (bool, optional) – Whether to return the centres of the bins. Defaults to True.

Returns:

Power in each radial bin. kr (npt.NDArray[np.float64]): Radial bins.

Return type:

power (npt.NDArray[np.float64])

Example

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from dotenv import dotenv_values
>>> from tqdm import tqdm
>>> import hybrid_jp as hj
>>> import hybrid_jp.analysis as hja
>>> if __name__ == "__main__":
...     # Environment variable DATA_DIR must be set to the directory containing
...     # the deck and sdf files
...     env = dotenv_values(".env")
...     data_dir = str(env["DATA_DIR"])
...     # Load deck and sdf files
...     deck = hja.load_deck(data_dir=data_dir)
...     SDFs, fpaths = hja.load_sdfs_para(
...         sdf_dir=data_dir,
...         dt=deck.output.dt_snapshot,
...         threads=7,
...         start=0,
...         stop=100,
...     )
...     # Unit conversions
...     for SDF in SDFs:
...         SDF.mag *= 1e9  # Convert to nT
...         SDF.mid_grid *= 1e-3  # Convert to km
...     # Create a CenteredShock object
...     cs = hja.CenteredShock(SDFs, deck)
...     # Set the number of chunks
...     N_CHUNKS = 10
...     cs.n_chunks = N_CHUNKS
...     # Get all frames in first downstream chunk
...     chunk = cs.downstream_start_chunk
...     all_frames = cs.valid_chunks[chunk, :]
...     valid_frames: hj.arrint = np.nonzero(all_frames)[0]
...     # Set fft properties
...     subdivisions = 8  # split each cell into (2^n)**2 subdivisions
...     num_radial_bins = 100  # These bins are logarithmically spaced
...     # Define containers for the power and radial bins
...     power = np.empty((valid_frames.size, num_radial_bins))
...     k = np.empty(num_radial_bins)
...     # Loop over all valid frames
...     for i, t_idx in tqdm(
...         enumerate(valid_frames),
...         total=valid_frames.size,
...         desc="Frame",
...     ):
...         power[i], k = hja.frame_power(
...             cs, chunk, t_idx, subdivisions, num_radial_bins
...         )
...     PSD = power.mean(axis=0)
...     fig, ax = plt.subplots()
...     ax.loglog(k, PSD, color="k", lw=1)
        ax.set_xlabel(r"$k\ [km^{-1}]$")
        ax.set_ylabel(r"$PSD(k)\ [nT^2\, km^{-2}]$")
...     plt.show()
hybrid_jp.analysis.ffts.hann_2d(nx: int, ny: int) ndarray[Any, dtype[float64]][source]#

Create a 2d hanning window.

https://stackoverflow.com/a/65948798

Example

>>> h2d = hann_2d(66, 160)
>>> X, Y = np.meshgrid(np.arange(66), np.arange(160))
>>> fig = plt.figure()
>>> ax = plt.axes(projection="3d")
>>> ax.contour3D(X, Y, h2d.T, 50)
>>> plt.show()
hybrid_jp.analysis.ffts.power_xy(arr: ndarray[Any, dtype[float64]], dx: float, dy: float) tuple[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]][source]#

Get power spectrum of an array f(x, y).

Parameters:
  • arr (npt.NDArray[np.float64]) – Array of shape (nx, ny)

  • dx (float) – Spacing between x points

  • dy (float) – Spacing between y points

Returns:

Power spectrum of arr fx (npt.NDArray[np.float64]): x frequencies fy (npt.NDArray[np.float64]): y frequencies

Return type:

Pxy (npt.NDArray[np.float64])

hybrid_jp.analysis.ffts.radial_power(Pxy: ndarray[Any, dtype[float64]], fx: ndarray[Any, dtype[float64]], fy: ndarray[Any, dtype[float64]], subdivisions: int, n_bins: int) tuple[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]][source]#

Get the radial bins for a power spectrum.

Args:

Returns:

Power in each radial bin. r_edges (npt.NDArray[np.float64]): Edges of the radial bins.

Return type:

Pr (npt.NDArray[np.float64])

hybrid_jp.analysis.ffts.subdivide_repeat(subdivisons: int, arrxy: ndarray[Any, dtype[float64]], x: ndarray[Any, dtype[float64]], y: ndarray[Any, dtype[float64]]) tuple[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]][source]#

Subdivide an array and repeat the values.

Parameters:
  • subdivisons (int) – Number of subdivisions in each dimension.

  • arrxy (NDArray[np.float64]) – Array to subdivide.

  • x (NDArray[np.float64]) – x values.

  • y (NDArray[np.float64]) – y values.

Returns:

Subdivided array. x (NDArray[np.float64]): Subdivided x values. y (NDArray[np.float64]): Subdivided y values.

Return type:

arrxy (NDArray[np.float64])