Source code for superfreq.core

# coding: utf-8

# Third-party
from astropy.table import Table
import numpy as np

__all__ = ['check_for_primes', 'orbit_to_fs']


[docs]def check_for_primes(n, max_prime=41): """ Given an integer, ``n``, ensure that it doest not have large prime divisors, which can wreak havok for FFT's. If needed, will decrease the number. Parameters ---------- n : int Integer number to test. Returns ------- n2 : int Integer combed for large prime divisors. """ m = n f = 2 while (f**2 <= m): if m % f == 0: m /= f else: f += 1 if m >= max_prime and n >= max_prime: n -= 1 n = check_for_primes(n) return n
[docs]def orbit_to_fs(orbit, units, style='laskar'): r""" Convert the orbit (position and velocity time series) into complex time series to be analyzed by `SuperFreq`. For `style=='laskar'`, assumes the standard complex time series .. math:: f_i = q_i + i\,p_i where :math:`q_i,p_i` are the coordinate and conjugate momenta (e.g., velocity for m=1). Parameters ---------- orbit : :class:`gala.dynamics.CartesianOrbit` The input orbit. units : :class:`gala.units.UnitSystem` The unit system. style : str (optional) Currently only supports `style = 'laskar'`. Returns ------- fs : tuple """ style = str(style).lower().strip() if style != 'laskar': raise ValueError("Currently only supports style = 'laskar'") q = np.squeeze(orbit.pos.xyz.decompose(units).value) p = np.squeeze(orbit.vel.d_xyz.decompose(units).value) if q.ndim > 2: raise ValueError("This function only supports converting single " "orbits, not a collection of orbits.") elif q.ndim < 2: raise ValueError("The orbit must contain more than one timestep.") fs = [q[i] + 1j*p[i] for i in range(q.shape[0])] return fs
class SuperFreqResult: def __init__(self, fund_freqs, freq_mode_table, fund_freqs_idx): self.fund_freqs = fund_freqs self.fund_freqs_idx = fund_freqs_idx self.freq_mode_table = Table(freq_mode_table) # derived / computed self.fund_freq_amps = np.asarray(self.freq_mode_table[self.fund_freqs_idx]['|A|']) def model_f(self, t, component_idx): """ Parameters ---------- t : array_like Array of times to evaluate the fourier sum model time series. component_idx : int The component to create the model time series for (e.g., the index of `fs`). Returns ------- model_f : :class:`numpy.ndarray` """ t = np.asarray(t) tbl = self.freq_mode_table[self.freq_mode_table['idx'] == component_idx] X = tbl['A'][None] * np.exp(1j*tbl['freq'][None] * t[:,None]) model_f = X.sum(axis=1) return model_f