LombScargle occasionally returns all-NaN powers · Issue #10070 · astropy/astropy · GitHub
Skip to content

LombScargle occasionally returns all-NaN powers #10070

Open

Description

@megbedell

Description

I want to use LombScargle to calculate the spectral window function of my observations, but sometimes I get an array of NaNs returned for powers. I'm not sure what governs the conditions for this error, but so far I've only encountered it when the input y grid is populated with a single value.

Expected behavior

Input an array t and a same-sized array y where all y-values are 1, get back some powers corresponding to the window function.

Actual behavior

Sometimes this works as expected. Other times, the output powers are an array of NaNs and the following warning is raised:

/Users/mbedell/miniconda3/envs/exoplanet/lib/python3.8/site-packages/astropy/timeseries/periodograms/lombscargle/implementations/fast_impl.py:125: RuntimeWarning: invalid value encountered in true_divide
power /= YY

Steps to Reproduce

Here is a snippet of code that reproduces the error:

from astropy.timeseries import LombScargle
np.random.seed(42)
N = 180
xs = np.arange(N) + np.random.normal(0., 0.1, N)
ys = np.ones_like(xs)
frequency, power = LombScargle(xs, ys).autopower(method='fast')
np.isfinite(power).any()

(should raise a warning and return False)

Changes to the above code that do not fix the error:

  • changing autopower method (I have tried 'slow' and 'chi2' with same results)
  • changing the random seed/rerunning the randomization
  • specifying a frequency grid as an input
  • making the xs grid perfectly uniformly spaced (no random perturbations)

Changes to the above code that do fix the error and return sensible powers:

  • changing N to nearly any other integer (I haven't tried an exhaustive list but for example 179 or 181 work just fine, as do other random ones I've tried. However, N = 180 is definitely not the only number that can reproduce this bug - N = 256 behaves similarly.)
  • scaling ys by some factor - this fixes the error if and only if the factor is not a multiple of 180, as far as I can tell. That is, ys = np.ones_like(xs)/100 fixes the error, but ys = np.ones_like(xs)/180 does not. Again, I haven't tried factors exhaustively, so take that theory with a grain of salt.
  • making the values of ys different from each other, e.g.:
    ys = np.ones_like(xs) * np.random.normal(1., 0.01, N)

System Details

macOS-10.15.3-x86_64-i386-64bit
Python 3.8.2 | packaged by conda-forge | (default, Mar 23 2020, 17:55:48)
[Clang 9.0.1 ]
Numpy 1.18.1
astropy 4.0
Scipy 1.4.1

Activity

  1. pllim commented on Mar 24, 2020

    @pllim
    Member

    @bsipocz , you are familiar with this functionality, right?

  2. dhomeier commented on Apr 4, 2020

    @dhomeier
    Contributor

    I want to use LombScargle to calculate the spectral window function of my observations, but sometimes I get an array of NaNs returned for powers. I'm not sure what governs the conditions for this error, but so far I've only encountered it when the input y grid is populated with a single value.

    Expected behavior

    Input an array t and a same-sized array y where all y-values are 1, get back some powers corresponding to the window function.

    @megbedell you've certainly spotted some mysterious behaviour here, but I don't think your attempts with a rescaled ys return the desired result either - trying this with different choices of method I found constant power of 0.0 for slow, near-constant 1.0 (!) for chi2, and a very noisy spectrum that showed indeed hints of the windowing function (peaks at integer frequencies), but diverging towards low frequencies.
    The slow result is indeed the correct one for that case, since LombScargle by default is using the auto-centred version of the spectrum, i.e. Eq. 2 of VanderPlas & Ivecić 2015 with y_k - <y>, i.e. all zeros in the numerator in the case of your constant ys!
    The NaNs are a result of the default normalisation over the weighted square of the (centred) input YY; apparently you are just getting nonzero values thanks to numerical noise for some scaling factors, e.g.

    In [49]: np.dot(np.ones(180).T/180, ys*179 - np.dot(ys*179, np.ones(180)/180))                                                                                                            
    Out[49]: -2.842170943040401e-14
    
    In [50]: np.dot(np.ones(180).T/180, ys*180 - np.dot(ys*180, np.ones(180)/180))                                                                                                            
    Out[50]: 0.0
    

    You can avoid the NaNs by selecting LombScargle(xs, ys, normalization='psd'), which does not divide by any power of Y, but what you really want is probably a nonzero output of the power spectrum that does give you the desired signal of the window function:

    frequency, power = LombScargle(xs, ys, fit_mean=False, center_data=False).autopower()
    

    This seems to produce consistent and sensible spectra for all methods.

    I think for the other cases it would be reasonable to add a check for YY != 0.0 and either raise an exception, or a warning and return the power directly (which should be all zero then anyway).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions