Home | Trees | Indices | Help |
---|
|
Contains many different periodogram calculations
Given a time series of the form
>>> times = np.linspace(0,1,1000) >>> signal = np.sin(times)
The basic interface is
>>> freq,ampl = scargle(times,signal)
If you give no extra information, default values for the start, end and step frequency will be chosen. See the 'defaults_pergram' decorator for a list of keywords common to all periodogram calculations.
Many periodograms can be computed in parallel, by supplying an extra keyword 'threads':
>>> freq,ampl = scargle(times,signal,threads=2)
Warning: the timeseries must be sorted in time and cannot contain the same timepoint twice. Otherwise, a 'ValueError, concatenation problem' can occur.
If something goes wrong in the periodogram computation, be sure to run check_input on your input data. This will print out some basic diagnostics to see if your data are valid.
The periodogram functions are written such that they never exceed the value of the Nyquist frequency. This behaviour can be changed.
By default, the Nyquist frequency is defined as half of the inverse
of the smallest time step in the data. That is, the
nyq_stat
variable is set to the function
np.min
. If you prefer the Nyquist to be defined as the
median, set the nyq_stat
variable for any periodogram to
np.median
. If you want a more complex or self-defined
function, that is also acceptable. If you give a number to
nyq_stat
, nothing will be computed but that value will be
considered the nyquist frequency.
>>> import time
The timeseries is generated for N=500,1000,2000,5000,10000,20000,50000
>>> techniques = ['scargle','deeming','gls','fasper', ... 'schwarzenberg_czerny','pdm','box'] >>> Ns = [1000,2000,5000,10000,20000,30000] >>> for tech in techniques[:0]: ... freqs = [] ... clock = [] ... for N in Ns: ... times = np.linspace(0,1,N) ... signal = np.sin(times) + np.random.normal(size=N) ... c0 = time.time() ... freq,ampl = locals()[tech](times,signal) ... clock.append(time.time()-c0) ... freqs.append(len(freq)) ... p = pl.plot(freqs,clock,'o-',label=tech) ... print tech,np.polyfit(np.log10(np.array(freqs)),np.log10(np.array(clock)),1) >>> #p = pl.legend(loc='best',fancybox=True) >>> #q = p.get_frame().set_alpha(0.5) >>> #p,q = pl.xlabel('Number of frequencies'),pl.ylabel('Seconds')
]]include figure]]ivs_timeseries_pergram_speeds.png]
We generate a sinusoidal signal, add some noise and compute the periodogram with the different methods.
>>> times = np.sort(np.random.uniform(size=500,low=0,high=100)) >>> signal = np.sin(2*np.pi/10.*times) >>> signal += np.random.normal(size=500)
Fourier based periodgrams suited for unequidistant data: scargle, deeming, fasper and schwarzenberg_czerny.
>>> f1,a1 = scargle(times,signal,fn=0.35) >>> f2,a2 = fasper(times,signal,fn=0.35) >>> f3,a3 = deeming(times,signal,fn=0.35) >>> f4,a4 = scargle(times,signal,norm='power',fn=0.35) >>> f5,a5 = schwarzenberg_czerny(times,signal,fn=0.35,nh=1,mode=2)
>>> p = pl.figure() >>> p = pl.subplot(121) >>> p = pl.plot(f1,a1,'k-',lw=4,label='scargle') >>> p = pl.plot(f2,a2,'r--',lw=4,label='fasper') >>> p = pl.plot(f3,a3,'b-',lw=2,label='deeming') >>> p = pl.xlim(f1[0],f1[-1]) >>> leg = pl.legend(fancybox=True,loc='best') >>> leg.get_frame().set_alpha(0.5) >>> p = pl.subplot(122) >>> p = pl.plot(f4,a4,'k-',lw=2,label='scargle') >>> p = pl.plot(f5,a5/2.,'r--',lw=2,label='schwarzenberg-czerny') >>> p = pl.xlim(f1[0],f1[-1]) >>> leg = pl.legend(fancybox=True,loc='best') >>> leg.get_frame().set_alpha(0.5)
]]include figure]]ivs_timeseries_pergrams_fourier.png]
Least-square fitting: gls and kepler.
>>> f1,a1 = gls(times,signal,fn=0.35) >>> f2,a2 = kepler(times,signal,fn=0.35)
>>> p = pl.figure() >>> p = pl.plot(f1,a1,'k-',lw=2,label='gls') >>> p = pl.plot(f2,a2,'r--',lw=2,label='kepler') >>> p = pl.xlim(f1[0],f1[-1]) >>> leg = pl.legend(fancybox=True,loc='best') >>> leg.get_frame().set_alpha(0.5)
]]include figure]]ivs_timeseries_pergrams_lsq.png]
Phase folding techniques: box and pdm
>>> f1,a1 = box(times,signal,fn=0.35) >>> f2,a2 = pdm(times,signal,fn=0.35)
>>> p = pl.figure() >>> p = pl.plot(f1,a1,'k-',lw=2,label='box') >>> p = pl.plot(f2,a2,'r--',lw=2,label='pdm') >>> p = pl.xlim(f1[0],f1[-1]) >>> leg = pl.legend(fancybox=True,loc='best') >>> leg.get_frame().set_alpha(0.5)
]]include figure]]ivs_timeseries_pergrams_phase.png]
|
|||
Periodograms | |||
---|---|---|---|
array,array |
|
||
array,array |
|
||
array,array |
|
||
array,array |
|
||
array,array |
|
||
array,array |
|
||
array |
|
||
ndarray |
|
||
|
|||
array,array |
|
||
array,array |
|
||
array |
|
||
array,array |
|
||
array,array |
|
||
array,array |
|
||
array |
|
||
Pure Python versions | |||
array |
|
||
|
|||
Helper functions | |||
array |
|
||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
|||
logger = logging.getLogger("TS.PERGRAMS")
|
|
Scargle periodogram of Scargle (1982). Several options are available (possibly combined):
This definition makes use of a Fortran-routine written by Jan Cuypers, Conny Aerts and Peter De Cat. A slightly adapted version is used for the weighted version (adapted by Pieter Degroote). Through the option "norm", it's possible to norm the periodogram as to get a periodogram that has a known statistical distribution. Usually, this norm is the variance of the data (NOT of the noise or residuals, see Schwarzenberg- Czerny 1998!). Also, it is possible to retrieve the power density spectrum in units of [ampl**2/frequency]. In this routine, the normalisation constant is taken to be the total time span T. Kjeldsen (2005) chooses to multiply the power by the 'effective length of the observing run', which is calculated as the reciprocal of the area under spectral window (in power, and take 2*Nyquist as upper frequency value). REMARK: this routine does not automatically remove the average. It is the user's responsibility to do this adequately: e.g. subtract a weighted average if one computes the weighted periodogram!!
|
Fasper periodogram from Numerical Recipes. Normalisation here is not correct!!
|
Deeming periodogram of Deeming et al (1975). Thanks to Jan Cuypers
|
Generalised Least Squares periodogram of Zucher et al (2010).
|
Cleaned Fourier periodogram of Roberts et al (1987) Parallization probably isn't such a good idea here because of the frequency bins. Fortran module probably from John Telting. Should always start from zero, so f0 is not an option Generate some signal with heavy window side lobes: >>> times_ = np.linspace(0,150,1000) >>> times = np.array([times_[i] for i in xrange(len(times_)) if (i%10)>7]) >>> signal = np.sin(2*pi/10*times) + np.random.normal(size=len(times)) Compute the scargle periodogram as a reference, and compare with the the CLEAN periodogram with different gains. >>> niter,freqbins = 10,[0,1.2] >>> p1 = scargle(times,signal,fn=1.2,norm='amplitude',threads=2) >>> p2 = clean(times,signal,fn=1.2,gain=1.0,niter=niter,freqbins=freqbins) >>> p3 = clean(times,signal,fn=1.2,gain=0.1,niter=niter,freqbins=freqbins) Make a figure of the result: >>> p=pl.figure() >>> p=pl.plot(p1[0],p1[1],'k-',label="Scargle") >>> p=pl.plot(p2[0],p2[1],'r-',label="Clean (g=1.0)") >>> p=pl.plot(p3[0],p3[1],'b-',label="Clean (g=0.1)") >>> p=pl.legend() ]]include figure]]ivs_timeseries_pergrams_clean.png]
|
Multi harmonic periodogram of Schwarzenberg-Czerny (1996). This periodogram follows an F-distribution, so it is possible to perform hypothesis testing. If the number of the number of harmonics is 1, then this peridogram reduces to the Lomb-Scargle periodogram except for its better statistic behaviour. This script uses a Fortran procedure written by Schwarzenberg-Czerny. Modes:
|
Computes the modulus square of the fourier transform. Unit: square of the unit of signal. Time points need not be equidistant. The normalisation is such that a signal A*sin(2*pi*nu_0*t) gives power A^2 at nu=nu_0
|
Computes the power spectrum of a signal using a discrete Fourier transform. The main difference between DFTpower and DFTpower2, is that the latter allows for non-equidistant frequencies for which the power spectrum will be computed.
|
Compute Discrete Fourier Transform for unevenly spaced data ( Scargle, 1989). Doesn't work yet! It is recommended to start f0 at 0. It is recommended to stop fn at the nyquist frequency This makes use of a FORTRAN algorithm written by Scargle (1989).
|
Computes power spectrum of an equidistant time series 'signal' using the FFT algorithm. The length of the time series need not be a power of 2 (zero padding is done automatically). Normalisation is such that a signal A*sin(2*pi*nu_0*t) gives power A^2 at nu=nu_0 (IF nu_0 is in the 'freq' array)
|
Computes the power density of an equidistant time series 'signal', using the FFT algorithm. The length of the time series need not be a power of 2 (zero padding is done automatically).
|
Compute the weighted power spectrum of a time signal. For each given frequency a weighted sine fit is done using chi-square minimization.
|
Phase Dispersion Minimization of Jurkevich-Stellingwerf (1978) This definition makes use of a Fortran routine written by Jan Cuypers and Conny Aerts. Inclusion of linear frequency shift by Pieter Degroote (see Cuypers 1986) Inclusion of binary orbital motion by Pieter Degroote (see Shibahashi & Kurtz 2012). When orbits are added, times must be in days, then asini is in AU. For circular orbits, give only forbit and asini.
|
Box-Least-Squares spectrum of Kovacs et al (2002). [ see Kovacs, Zucker & Mazeh 2002, A&A, Vol. 391, 369 ] This is the slightly modified version of the original BLS routine by considering Edge Effect (EE) as suggested by Peter R. McCullough [ pmcc@stsci.edu ]. This modification was motivated by considering the cases when the low state (the transit event) happened to be devided between the first and last bins. In these rare cases the original BLS yields lower detection efficiency because of the lower number of data points in the bin(s) covering the low state. For further comments/tests see www.konkoly.hu/staff/kovacs.html Transit fraction and precision are given by nb,qmi and qma Remark: output parameter parameter contains: [frequency,depth,transit fraction width,fractional start, fraction end]
|
Keplerian periodogram of Zucker et al (2010).
|
Weighted Wavelet Z-transform of Foster (1996) Computes "Weighted Wavelet Z-Transform" which is a type of time-frequency diagram more suitable for non-equidistant time series. See: G. Foster, 1996, Astronomical Journal, 112, 1709 The result can be plotted as a colorimage (imshow in pylab). Mind the max, min order for position. It's often useful to try log(Z) and/or different sigmas.
|
Computes the theta-statistics to do a Phase Dispersion Minimisation. See Stellingwerf R.F., 1978, ApJ, 224, 953) Joris De Ridder Inclusion of linear frequency shift by Pieter Degroote (see Cuypers 1986)
|
function fasper Given abscissas x (which need not be equally spaced) and ordinates y, and given a desired oversampling factor ofac (a typical value being 4 or larger). this routine creates an array wk1 with a sequence of nout increasing frequencies (not angular frequencies) up to hifac times the "average" Nyquist frequency, and creates an array wk2 with the values of the Lomb normalized periodogram at those frequencies. The arrays x and y are not altered. This routine also returns jmax such that wk2(jmax) is the maximum element in wk2, and prob, an estimate of the significance of that maximum against the hypothesis of random noise. A small value of prob indicates that a significant periodic signal is present. Reference: Press, W. H. & Rybicki, G. B. 1989 ApJ vol. 338, p. 277-280. Fast algorithm for spectral analysis of unevenly sampled data (1989ApJ...338..277P) Arguments: X : Abscissas array, (e.g. an array of times). Y : Ordinates array, (e.g. corresponding counts). Ofac : Oversampling factor. Hifac : Hifac * "average" Nyquist frequency = highest frequency for which values of the Lomb normalized periodogram will be calculated. Returns: Wk1 : An array of Lomb periodogram frequencies. Wk2 : An array of corresponding values of the Lomb periodogram. Nout : Wk1 & Wk2 dimensions (number of calculated frequencies) Jmax : The array index corresponding to the MAX( Wk2 ). Prob : False Alarm Probability of the largest Periodogram value MACC : Number of interpolation points per 1/4 cycle of highest frequency History: 02/23/2009, v1.0, MF Translation of IDL code (orig. Numerical recipies) |
Computes the modulus square of the window function of a set of time points at the given frequencies. The time point need not be equidistant. The normalisation is such that 1.0 is returned at frequency 0.
|
Check the input arguments for periodogram calculations for mistakes. If you get an error when trying to compute a periodogram, and you don't understand it, just feed the input you gave to this function, and it will perform some basic checks. |
Given an array yy(0:n-1), extirpolate (spread) a value y into m actual array elements that best approximate the "fictional" (i.e., possible noninteger) array element number x. The weights used are coefficients of the Lagrange interpolating polynomial Arguments: y : yy : n : x : m : Returns: |
Returns the peak false alarm probabilities Hence the lower is the probability and the more significant is the peak |
Compute the probability to observe a peak in the Scargle periodogram. If Example simulation: >>> times = np.linspace(0,1,5000) >>> N = 500 >>> probs = np.zeros(N) >>> peaks = np.zeros(N) >>> for i in range(N): ... signal = np.random.normal(size=len(times)) ... f,s = scargle(times,signal,threads='max',norm='distribution') ... peaks[i] = s.max() ... probs[i] = scargle_probability(s.max(),times,f) Now make a plot: >>> p = pl.figure() >>> p = pl.subplot(131) >>> p = pl.plot(probs,'ko') >>> p = pl.plot([0,N],[0.01,0.01],'r-',lw=2) >>> p = pl.subplot(132) >>> p = pl.plot(peaks[np.argsort(peaks)],probs[np.argsort(peaks)],'ro') >>> p = pl.plot(peaks[np.argsort(peaks)],1-(1-np.exp(-np.sort(peaks)))**(10000.),'g-') >>> #p = pl.plot(peaks[np.argsort(peaks)],1-(1-(1-np.sort(peaks)/2500.)**2500.)**(10000.),'b--') >>> p = pl.subplot(133) >>> for i in np.logspace(-3,0,100): ... p = pl.plot([i*100],[np.sum(probs<i)/float(N)*100],'ko') >>> p = pl.plot([1e-6,100],[1e-6,100],'r-',lw=2) >>> p = pl.xlabel('Should observe this many points below threshold') >>> p = pl.ylabel('Observed this many points below threshold') ]]include figure]]ivs_timeseries_pergrams_prob.png] |
Home | Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Fri Mar 30 10:45:19 2018 | http://epydoc.sourceforge.net |