示例#1
0
    def test_get_TOA2(self):
        np.random.seed(1234)
        period = 1.2
        tstart = 122
        start_phase = 0.2123
        phases = np.arange(0, 1, 1 / 32)
        template = _template_fun(phases, start_phase, 10, 20)
        prof = np.random.poisson(template)

        toa, toaerr = \
            get_TOA(prof, period, tstart,
                    template=_template_fun(phases, 0, 1, 0), nstep=200)

        real_toa = tstart + start_phase * period
        assert (real_toa >= toa - toaerr * 3) & (real_toa <= toa + toaerr * 3)
示例#2
0
    def test_get_TOA2(self):
        np.random.seed(1234)
        period = 1.2
        tstart = 122
        start_phase = 0.2123
        phases = np.arange(0, 1, 1 / 32)
        template = _template_fun(phases, start_phase, 10, 20)
        prof = np.random.poisson(template)

        toa, toaerr = \
            get_TOA(prof, period, tstart,
                    template=_template_fun(phases, 0, 1, 0), nstep=200)

        real_toa = tstart + start_phase * period
        assert (real_toa >= toa - toaerr * 3) & (real_toa <= toa + toaerr * 3)
示例#3
0
def get_TOAs_from_events(events, folding_length, *frequency_derivatives,
                         **kwargs):
    """Get TOAs of pulsation.

    Parameters
    ----------
    events : array-like
        event arrival times
    folding_length : float
        length of sub-intervals to fold
    *frequency_derivatives : floats
        pulse frequency, first derivative, second derivative, etc.

    Other parameters
    ----------------
    pepoch : float, default None
        Epoch of timing solution, in the same units as ev_times. If none, the
        first event time is used.
    mjdref : float, default None
        Reference MJD
    template : array-like, default None
        The pulse template
    nbin : int, default 16
        The number of bins in the profile (overridden by the dimension of the
        template)
    timfile : str, default 'out.tim'
        file to save the TOAs to (if PINT is installed)
    gti: [[g0_0, g0_1], [g1_0, g1_1], ...]
         Good time intervals. Defaults to None
    quick: bool
         If True, use a quicker fitting algorithms for TOAs. Defaults to False
    position: `astropy.SkyCoord` object
         Position of the object

    Returns
    -------
    toas : array-like
        list of times of arrival. If ``mjdref`` is specified, they are
        expressed as MJDs, otherwise in MET
    toa_err : array-like
        errorbars on TOAs, in the same units as TOAs.
    """
    import matplotlib.pyplot as plt
    template = kwargs['template'] if 'template' in kwargs else None
    mjdref = kwargs['mjdref'] if 'mjdref' in kwargs else None
    nbin = kwargs['nbin'] if 'nbin' in kwargs else 16
    pepoch = kwargs['pepoch'] if 'pepoch' in kwargs else None
    timfile = kwargs['timfile'] if 'timfile' in kwargs else 'out.tim'
    gti = kwargs['gti'] if 'gti' in kwargs else None
    label = kwargs['label'] if 'label' in kwargs else None
    quick = kwargs['quick'] if 'quick' in kwargs else False
    position = kwargs['position'] if 'position' in kwargs else None

    pepoch = assign_value_if_none(pepoch, events[0])
    gti = assign_value_if_none(gti, [[events[0], events[-1]]])
    # run exposure correction only if there are less than 1000 pulsations
    # in the interval
    length = gti.max() - gti.min()
    expocorr = folding_length < (1000 / frequency_derivatives[0])

    if template is not None:
        nbin = len(template)
        additional_phase = np.argmax(template) / nbin
    else:
        phase, profile, profile_err = \
            fold_events(copy.deepcopy(events), *frequency_derivatives,
                        ref_time=pepoch, gtis=copy.deepcopy(gti),
                        expocorr=expocorr, nbin=nbin)
        fit_pars_save, _, _ = \
            fit_profile_with_sinusoids(profile, profile_err, nperiods=1,
                                       baseline=True)
        template = std_fold_fit_func(fit_pars_save, phase)
        fig = plt.figure()
        plt.plot(phase, profile, drawstyle='steps-mid')
        plt.plot(phase, template, drawstyle='steps-mid')
        plt.savefig(timfile.replace('.tim', '') + '.png')
        plt.close(fig)
        # start template from highest bin!
        # template = np.roll(template, -np.argmax(template))
        template *= folding_length / length
        template_fine = std_fold_fit_func(fit_pars_save,
                                          np.arange(0, 1, 0.001))
        additional_phase = np.argmax(template_fine) / len(template_fine)

    starts = np.arange(gti[0, 0], gti[-1, 1], folding_length)

    toas = []
    toa_errs = []
    for start in show_progress(starts):
        stop = start + folding_length
        good = (events >= start) & (events < stop)
        events_tofold = events[good]
        if len(events_tofold) < nbin:
            continue
        gtis_tofold = \
            copy.deepcopy(gti[(gti[:, 0] < stop) & (gti[:, 1] > start)])
        gtis_tofold[0, 0] = start
        gtis_tofold[-1, 1] = stop

        local_f = frequency_derivatives[0]
        for i_f, f in enumerate(frequency_derivatives[1:]):
            local_f += 1 / np.math.factorial(i_f + 1) * (start -
                                                         pepoch)**(i_f + 1) * f

        fder = copy.deepcopy(list(frequency_derivatives))
        fder[0] = local_f
        phase, profile, profile_err = \
            fold_events(events_tofold, *fder,
                        ref_time=start, gtis=gtis_tofold,
                        expocorr=expocorr, nbin=nbin)

        # BAD!BAD!BAD!
        # [[Pay attention to time reference here.
        # We are folding wrt pepoch, and calculating TOAs wrt start]]

        toa, toaerr = \
            get_TOA(profile, 1/frequency_derivatives[0], start,
                    template=template, additional_phase=additional_phase,
                    quick=quick, debug=True)
        toas.append(toa)
        toa_errs.append(toaerr)

    toas, toa_errs = np.array(toas), np.array(toa_errs)

    if mjdref is not None:
        toas = toas / 86400 + mjdref
        toa_errs = toa_errs * 1e6
        if HAS_PINT:
            label = assign_value_if_none(label, 'hendrics')
            toa_list = _load_and_prepare_TOAs(toas, errs_us=toa_errs)
            # workaround until PR #368 is accepted in pint
            toa_list.table['clkcorr'] = 0
            toa_list.write_TOA_file(timfile, name=label, format='Tempo2')

        print('TOA(MJD)  TOAerr(us)')
    else:
        print('TOA(MET)  TOAerr(us)')

    for t, e in zip(toas, toa_errs):
        print(t, e)

    return toas, toa_errs