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)
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