Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publication output #1582

Closed
paulray opened this issue Jun 1, 2023 · 6 comments · Fixed by #1621
Closed

Publication output #1582

paulray opened this issue Jun 1, 2023 · 6 comments · Fixed by #1621
Labels
student Good student project

Comments

@paulray
Copy link
Member

paulray commented Jun 1, 2023

It would be nice if PINT had a function to write out a timing model in LaTeX table form, suitable for pasting into a publication. Tempo2 has such a plugin.

@scottransom
Copy link
Member

I have a lot of python code that does this. Could be fairly easy to make a basic one. Although the problem is that there are lots of special cases...

@abhisrkckl
Copy link
Contributor

Just out of curiosity, what is the tempo2 plugin called?

@paulray
Copy link
Member Author

paulray commented Jun 8, 2023

If you run this command, it will generate table.tex:

tempo2 -output publish -f NGC6440E.par NGC6440E.tim

and here is the output:

\documentclass{article}
\begin{document}
\begin{table}
\caption{Parameters for PSR 1748$-$2021E}
\begin{tabular}{ll}
\hline\hline
\multicolumn{2}{c}{Fit and data-set} \\
\hline
Pulsar name\dotfill & J1748$-$2021E \\ 
MJD range\dotfill & 53478.3---54187.6 \\ 
Data span (yr)\dotfill & 1.94 \\ 
Number of TOAs\dotfill & 62 \\
Rms timing residual ($\mu s$)\dotfill & 31.7 \\
Weighted fit\dotfill &  N \\ 
\hline
\multicolumn{2}{c}{Measured Quantities} \\ 
\hline
Right ascension, $\alpha$ (hh:mm:ss)\dotfill &  17:48:52.8003(3) \\ 
Declination, $\delta$ (dd:mm:ss)\dotfill & $-$20:21:29.37(6) \\ 
Pulse frequency, $\nu$ (s$^{-1}$)\dotfill & 61.48547655437(3) \\ 
First derivative of pulse frequency, $\dot{\nu}$ (s$^{-2}$)\dotfill & $-$1.181(3)$\times 10^{-15}$ \\ 
Dispersion measure, DM (cm$^{-3}$pc)\dotfill & 224.19(4) \\ 
\hline
\multicolumn{2}{c}{Set Quantities} \\ 
\hline
Epoch of frequency determination (MJD)\dotfill & 53750 \\ 
Epoch of position determination (MJD)\dotfill & 53750 \\ 
Epoch of dispersion measure determination (MJD)\dotfill & 53750 \\ 
NE_SW (cm^-3)\dotfill & 0 \\ 
\hline
\multicolumn{2}{c}{Derived Quantities} \\
\hline
$\log_{10}$(Characteristic age, yr) \dotfill & 8.92 \\
$\log_{10}$(Surface magnetic field strength, G) \dotfill & 9.36 \\
$\log_{10}$(Edot, ergs/s) \dotfill & 33.46 \\
\hline
\multicolumn{2}{c}{Assumptions} \\
\hline
Clock correction procedure\dotfill & TT(BIPM2019) \\
Solar system ephemeris model\dotfill & DE421 \\
Binary model\dotfill & NONE \\
TDB units (tempo1 mode)\dotfill & Y \\
FB90 time ephemeris (tempo1 mode)\dotfill & Y \\
Shapiro delay due to planets\dotfill & N \\
Tropospheric delay\dotfill & N \\
Dilate frequency\dotfill & N \\
Electron density at 1 AU (cm$^{-3}$)\dotfill & 0.00 \\ 
Model version number\dotfill & 2.00 \\ 
\hline
\end{tabular}
\end{table}
\end{document}

@scottransom
Copy link
Member

Here is an example script that uses the uncertainties package, and PRESTO's parfile reader to generate a nice LaTeX table. We would want to modify this to use PINT's model information, obviously. But this should give an idea of what some of the code could look like. Note that this version puts multiple pulsars on each row.

import sys
import numpy as np
import presto.parfile as pp
import presto.psr_utils as pu
import uncertainties as unc

numdigits = 1
Mpsr = 1.4
errfac = 1.0

def valerr(val, err, digits=numdigits, errfac=errfac):
    x = unc.ufloat(val, err * errfac)
    fstr = "{:.%duSL}" % digits
    return fstr.format(x)

def split_RAJ(raj, raj_err, errfac=errfac):
    h,m,s = raj.split(':')
    s_str = valerr(float(s), raj_err, errfac=errfac)
    if float(s) < 10.0:
        s_str.zfill(len(s_str)+1)
    s_str = s_str.replace('.', '\\fs')
    return r"$%s^{\rm h}\;%s^{\rm m}\;0%s$" % (h, m, s_str)

def split_DECJ(decj, decj_err, errfac=errfac):
    d,m,s = decj.split(':')
    s_str = valerr(float(s), decj_err, errfac=errfac)
    if float(s) < 10.0:
        s_str.zfill(len(s_str)+1)
    s_str = s_str.replace('.', '\\farcs')
    return r"$%s\degrees\;%s\amin\;%s$" % (d, m, s_str)

def mf_with_err(x, xerr, pb, pberr):
    # Return the mass function with its error using error propagation
    # x is in lt-sec and pb is in days
    x = unc.ufloat(x, xerr)
    pb = unc.ufloat(pb, pberr)
    mf = pu.mass_funct(pb, x)
    return (mf.n, mf.s)

parname = "1748-2446am_std.par"
psrname = "J1748$-$2446am"
psrs = [pp.psr_par(parname)]

print(r"""\begin{deluxetable}{lc}
\tabletypesize{\footnotesize}
\tablecaption{PSR %s\label{tab1}}
\tablewidth{0pt}
\startdata""" % psrname)
print(r"\cutinhead{Timing Parameters}")
print(r"Right Ascension (RA, J2000) \dotfill & %s\\" % \
    tuple([split_RAJ(psr.RAJ, psr.RAJ_ERR) for psr in psrs]))
print(r"Declination     (DEC, J2000) \dotfill & %s\\" % \
    tuple([split_DECJ(psr.DECJ, psr.DECJ_ERR) for psr in psrs]))
print(r"Pulsar Period (ms) \dotfill & %s\\" % \
    tuple([valerr(psr.P0*1000.0, psr.P0_ERR*1000.0) for psr in psrs]))
print(r"Pulsar Frequency (Hz) \dotfill & %s\\" % \
    tuple([valerr(psr.F0, psr.F0_ERR) for psr in psrs]))
print(r"Frequency Derivative (Hz\,s$^{-1}$) \dotfill & %s\\" % \
    tuple([valerr(psr.F1, psr.F1_ERR) for psr in psrs]))
print(r"Reference Epoch (MJD) \dotfill & %.12g\\" % \
    tuple([psr.PEPOCH for psr in psrs]))
print(r"Dispersion Measure (pc cm$^{-3}$) \dotfill & %s\\" % \
    tuple([valerr(psr.DM, psr.DM_ERR) for psr in psrs]))
print(r"Orbital Period (days) \dotfill & %s\\" % \
    tuple([valerr(psr.PB, psr.PB_ERR) for psr in psrs]))
print(r"Projected Semi-Major Axis (lt-s)  \dotfill & %s\\" % \
    tuple([valerr(psr.A1, psr.A1_ERR) for psr in psrs]))
print(r"Orbital Eccentricity  \dotfill & %s\\" % \
    tuple([valerr(psr.ECC, psr.ECC_ERR) for psr in psrs]))
print(r"Epoch of Periastron (MJD) \dotfill & %s\\" % \
    tuple([valerr(psr.T0, psr.T0_ERR) for psr in psrs]))
print(r"Longitude of Periastron, $\omega$ (deg) \dotfill & %s\\" % \
    tuple([valerr(psr.OM, psr.OM_ERR) for psr in psrs]))
print(r"Time Derivative of $\omega$, $\dot\omega$ (deg\,yr$^{-1}$) \dotfill & %s\\" % \
    tuple([valerr(psr.OMDOT, psr.OMDOT_ERR) for psr in psrs]))
spans = [[psr.START, psr.FINISH] for psr in psrs]
spans = tuple([item for sublist in spans for item in sublist])
print(r"Span of Timing Data (MJD) \dotfill & %.0f$-$%.0f\\" % spans)
print(r"Number of TOAs  \dotfill & %.0f\\" % (217))
print(r"RMS TOA Residual ($\mu$s) \dotfill & %.1f\\" % (38.55))

print(r"\cutinhead{Derived Parameters}")
ve_pairs = []
for psr in psrs:
    ve_pairs.append(mf_with_err(psr.A1, psr.A1_ERR*errfac, psr.PB, psr.PB_ERR*errfac))
print(r"Mass Function (\msun) \dotfill & %s\\" % \
    tuple([valerr(*ve_pair) for ve_pair in ve_pairs]))
Mtot = pu.OMDOT_to_Mtot(psr.OMDOT, psr.PB, psr.E)
Mthi = pu.OMDOT_to_Mtot(psr.OMDOT+psr.OMDOT_ERR, psr.PB, psr.E)
Mtlo = pu.OMDOT_to_Mtot(psr.OMDOT-psr.OMDOT_ERR, psr.PB, psr.E)
Mtot_err = 0.5 * ((Mthi-Mtot) + (Mtot-Mtlo))
print(r"Total System Mass (\msun) \dotfill & %s\\" % \
    tuple([valerr(Mtot, Mtot_err*errfac)]))
print(r"Min Companion Mass (\msun) \dotfill & $\geq$\,%.2g\\" % \
    tuple([pu.companion_mass_limit(psr.PB, psr.A1, mpsr=Mpsr) for psr in psrs]))
print(r"Companion Mass (\msun) \dotfill & %.3g ($+$%.2g, $-$%.2g)\\" % \
    (0.1936, 0.114, 0.0233))
print(r"Pulsar Mass (\msun) \dotfill & %.4g ($+$%.2g, $-$%.2g)\\" % \
    (1.6492, 0.0369, 0.109))
print(r"Flux Density at 2\,GHz (mJy) \dotfill & %.2g" % \
    (0.06))
print(r"""\enddata

\tablecomments{Numbers in parentheses represent %g-$\sigma$""" % (errfac))
print(r"""uncertainties in the last digit.  The timing solution was
determined using {\tt TEMPO} with the DE436 Solar System Ephemeris and
the DD binary model. The time system used is Barycentric Dynamical
Time (TDB).  The minimum companion mass was calculated assuming a
pulsar mass of 1.4\,\msun.  The total system mass and 68\% central
confidence ranges on the masses of the pulsar and its companion were
determined assuming that $\dot\omega$ is due completely to general
relativity, and a random orbital inclination (i.e.~probability density
is constant in $\cos i$).}
\end{deluxetable}""")

@scottransom
Copy link
Member

I should have mentioned that that code was used to make Table 1 in Andersen & Ransom, 2018.

@dlakaplan
Copy link
Contributor

The method as_ufloat() may be useful to turn a parameter into an uncertainties.ufloat for printing or computing.

@paulray paulray added the student Good student project label Jun 23, 2023
@abhisrkckl abhisrkckl linked a pull request Aug 21, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
student Good student project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants