Esempio n. 1
0
def required_signal_power(power, n=1, confidence=0.99):
    """
    required_signal_power(power, n=1, confidence=0.99):
        Return the required power of a signal that will cause
        at least a power 'power' in a power spectrum a fraction
        'confidence' of the time.  This is the inverse of
        equation 16 in Groth, 1975, with solves for P_signal.
        If called with 'power' = P_detect the result is
        the search sensitivity.  If called with 'power' = P_max,
        then the result is the upper limit on the signal power
        in the power spectrum.
    """
    prob = 1.0 - confidence
    def func(x, power=power, prob=prob, n=n):
        return prob_power_series(power, x, n) - prob
    def dfunc(x, power=power, n=n):
        return power_probability(power, x, n)
    P_signal = newton_raphson(func, dfunc, 0.0001, 100.0)
    return P_signal
Esempio n. 2
0
def required_signal_power(power, n=1, confidence=0.99):
    """
    required_signal_power(power, n=1, confidence=0.99):
        Return the required power of a signal that will cause
        at least a power 'power' in a power spectrum a fraction
        'confidence' of the time.  This is the inverse of
        equation 16 in Groth, 1975, with solves for P_signal.
        If called with 'power' = P_detect the result is
        the search sensitivity.  If called with 'power' = P_max,
        then the result is the upper limit on the signal power
        in the power spectrum.
    """
    prob = 1.0 - confidence
    def func(x, power=power, prob=prob, n=n):
        return prob_power_series(power, x, n) - prob
    def dfunc(x, power=power, n=n):
        return power_probability(power, x, n)
    P_signal = newton_raphson(func, dfunc, 0.0001, 100.0)
    return P_signal
Esempio n. 3
0
def measure_phase(profile, template, sigma, fwhm):
    """
    measure_phase(profile, template, sigma, fwhm):
       TOA measurement technique from J. H. Taylor's talk
       _Pulsar_Timing_and_Relativistic_Gravity_.  Routine
       takes two profiles, the first measured and the
       second a high S/N template and determines the phase
       offset of 'profile' from 'template'.  Both profiles
       must have the same number of points.  'sigma' denotes
       the RMS noise level of the 'profile'.  'fwhm' is the
       approximate width of the template pulse (0-1).  The phase
       returned is cyclic (i.e. from 0-1).  The routine
       returns a tuple comtaining (tau, tau_err, b, b_err, a).
       Where 'tau' is the phase, 'B' is the scaling factor,
       and 'a' is the DC offset.  The error values are
       estimates of the 1 sigma errors.
    """
    from simple_roots import newton_raphson
    N = len(profile)
    if not (N == len(template)):
       print "Lengths of 'profile' and 'template' must"
       print "  be equal in measure_phase()."
       return 0.0
    ft = rfft(profile)
    p0 = ft[0].real
    # Nyquist freq
    ft[0] = complex(ft[0].imag, 0.0)
    P_k = abs(ft)
    frotate(P_k, len(ft), 1)
    Theta_k = np.arctan2(-ft.imag, ft.real)
    frotate(Theta_k, len(ft), 1)
    ft = rfft(template)
    s0 = ft[0].real
    # Nyquist freq
    ft[0] = complex(ft[0].imag, 0.0)
    S_k = abs(ft)
    frotate(S_k, len(ft), 1)
    Phi_k = np.arctan2(-ft.imag, ft.real)
    frotate(Phi_k, len(ft), 1)
    # Estimate of the noise sigma (This needs to be checked)
    # Note:  Checked 10 Jul 2000.  Looks OK.
    sig = sigma * np.sqrt(N)
    k = np.arange(len(ft), dtype='d') + 1.0
    def fn(tau, k=k, p=P_k, s=S_k, theta=Theta_k, phi=Phi_k):
       # Since Nyquist freq always has phase = 0.0
       k[-1] = 0.0
       return np.add.reduce(k * p * s *
                                 np.sin(phi - theta + k * tau))
    def dfn(tau, k=k, p=P_k, s=S_k, theta=Theta_k, phi=Phi_k):
       # Since Nyquist freq always has phase = 0.0
       k[-1] = 0.0
       return np.add.reduce(k * k * p * s *
                                 np.cos(phi - theta + k * tau))
    numphases = 200
    ddchidt = np.zeros(numphases, 'd')
    phases = np.arange(numphases, dtype='d') / \
             float(numphases-1) * TWOPI - PI
    for i in np.arange(numphases):
       ddchidt[i] = dfn(phases[i])
    maxdphase = phases[np.argmax(ddchidt)] + \
                0.5 * TWOPI / (numphases - 1.0)
    # Solve for tau
    tau = newton_raphson(fn, dfn, maxdphase - 0.5 * fwhm * TWOPI,
                         maxdphase + 0.5 * fwhm * TWOPI)
    # Solve for b
    c = P_k * S_k * np.cos(Phi_k - Theta_k + k * tau)
    d = np.add.reduce(S_k**2.0)
    b = np.add.reduce(c) / d
    # tau sigma
    tau_err = sig * np.sqrt(1.0 / (2.0 * b *
                                    np.add.reduce(k**2.0 * c)))
    # b sigma  (Note:  This seems to be an underestimate...)
    b_err = sig * np.sqrt(1.0 / (2.0 * d))
    # Solve for a
    a = (p0 - b * s0) / float(N)
    return (tau / TWOPI, tau_err / TWOPI, b, b_err, a)
Esempio n. 4
0
def measure_phase(profile, template, sigma, fwhm):
    """
    measure_phase(profile, template, sigma, fwhm):
       TOA measurement technique from J. H. Taylor's talk
       _Pulsar_Timing_and_Relativistic_Gravity_.  Routine
       takes two profiles, the first measured and the
       second a high S/N template and determines the phase
       offset of 'profile' from 'template'.  Both profiles
       must have the same number of points.  'sigma' denotes
       the RMS noise level of the 'profile'.  'fwhm' is the
       approximate width of the template pulse (0-1).  The phase
       returned is cyclic (i.e. from 0-1).  The routine
       returns a tuple comtaining (tau, tau_err, b, b_err, a).
       Where 'tau' is the phase, 'B' is the scaling factor,
       and 'a' is the DC offset.  The error values are
       estimates of the 1 sigma errors.
    """
    from simple_roots import newton_raphson
    N = len(profile)
    if not (N == len(template)):
        print "Lengths of 'profile' and 'template' must"
        print "  be equal in measure_phase()."
        return 0.0
    ft = rfft(profile)
    p0 = ft[0].real
    # Nyquist freq
    ft[0] = complex(ft[0].imag, 0.0)
    P_k = abs(ft)
    frotate(P_k, len(ft), 1)
    Theta_k = Num.arctan2(-ft.imag, ft.real)
    frotate(Theta_k, len(ft), 1)
    ft = rfft(template)
    s0 = ft[0].real
    # Nyquist freq
    ft[0] = complex(ft[0].imag, 0.0)
    S_k = abs(ft)
    frotate(S_k, len(ft), 1)
    Phi_k = Num.arctan2(-ft.imag, ft.real)
    frotate(Phi_k, len(ft), 1)
    # Estimate of the noise sigma (This needs to be checked)
    # Note:  Checked 10 Jul 2000.  Looks OK.
    sig = sigma * Num.sqrt(N)
    k = Num.arange(len(ft), dtype='d') + 1.0

    def fn(tau, k=k, p=P_k, s=S_k, theta=Theta_k, phi=Phi_k):
        # Since Nyquist freq always has phase = 0.0
        k[-1] = 0.0
        return Num.add.reduce(k * p * s * Num.sin(phi - theta + k * tau))

    def dfn(tau, k=k, p=P_k, s=S_k, theta=Theta_k, phi=Phi_k):
        # Since Nyquist freq always has phase = 0.0
        k[-1] = 0.0
        return Num.add.reduce(k * k * p * s * Num.cos(phi - theta + k * tau))

    numphases = 200
    ddchidt = Num.zeros(numphases, 'd')
    phases = Num.arange(numphases, dtype='d') / \
             float(numphases-1) * TWOPI - PI
    for i in Num.arange(numphases):
        ddchidt[i] = dfn(phases[i])
    maxdphase = phases[Num.argmax(ddchidt)] + \
                0.5 * TWOPI / (numphases - 1.0)
    # Solve for tau
    tau = newton_raphson(fn, dfn, maxdphase - 0.5 * fwhm * TWOPI,
                         maxdphase + 0.5 * fwhm * TWOPI)
    # Solve for b
    c = P_k * S_k * Num.cos(Phi_k - Theta_k + k * tau)
    d = Num.add.reduce(S_k**2.0)
    b = Num.add.reduce(c) / d
    # tau sigma
    tau_err = sig * Num.sqrt(1.0 / (2.0 * b * Num.add.reduce(k**2.0 * c)))
    # b sigma  (Note:  This seems to be an underestimate...)
    b_err = sig * Num.sqrt(1.0 / (2.0 * d))
    # Solve for a
    a = (p0 - b * s0) / float(N)
    return (tau / TWOPI, tau_err / TWOPI, b, b_err, a)
Esempio n. 5
0
if (0):
    # Use the following to generate the xs
    from simple_roots import newton_raphson

    rval = 0.0
    rs = Num.arange(n+1, dtype=Num.float)/n
    xs = Num.zeros(n+1, dtype=Num.float)
    def func(x):
        return Num.sin(2.0*Num.pi*x)/(2.0*Num.pi) + x - rval
    def dfunc(x):
        return Num.cos(2.0*Num.pi*x) + 1
    for (ii, rval) in enumerate(rs[:-1]):
        if (ii==n/2):
            xs[ii] = 0.5
        else:
            xs[ii] = newton_raphson(func, dfunc, 0.0, 1.0)
    xs[0] = 0.0
    xs[n] = 1.0
    cPickle.dump(xs, file("cosine_rand.pickle", "w"), 1)
else:
    pfile = os.path.join(os.environ['PRESTO'],
                         "lib", "python", "cosine_rand.pickle")
    xs = cPickle.load(file(pfile))

def cosine_rand(num):
    """cosine_rand(num):  Return num phases that are randomly distributed
          as per a sinusoid with maximum at phase=0 (0 < phase < 1).
    """
    rands = n*Num.random.random(num)
    indices = rands.astype(Num.int)
    fracts = rands-indices