25Some helper classes and functions for outputing html and LaTeX pages
28from __future__
import print_function
39 "COSIOTA":
"$\\cos{\\iota}$",
40 "PSI":
"$\\psi$ (rad)",
41 "PHI0":
"$\\phi_0$ (rad)",
47 "F1":
"$\\dot{f}$ (Hz/s)",
48 "F2":
"$\\ddot{f}$ (Hz/s$^2$)",
49 "F3":
"$f_3$ (Hz/s$^3$)",
50 "F4":
"$f_4$ (Hz/s$^4$)",
51 "F5":
"$f_5$ (Hz/s$^5$)",
52 "F6":
"$f_6$ (Hz/s$^6$)",
53 "F7":
"$f_7$ (Hz/s$^7$)",
54 "F8":
"$f_8$ (Hz/s$^8$)",
55 "F9":
"$f_9$ (Hz/s$^9$)",
56 "F10":
"$f_{10}$ (Hz/s$^{10}$)",
58 "PMRA":
"p.m. $\\alpha$ (rad/s)",
59 "PMDEC":
"p.m. $\\delta$ (rad/s)",
60 "PMDC":
"p.m. $\\delta$ (rad/s)",
62 "A1":
"$a \\sin{i}$ (lt s)",
63 "A1_2":
"$(a \\sin{i})_{2}$ (lt s)",
64 "A1_3":
"$(a \\sin{i})_{3}$ (lt s)",
67 "PB_2":
"$(P_b)_2$ (s)",
68 "PB_3":
"$(P_b)_3$ (s)",
70 "T0_2":
"$(T_0)_2$ (s)",
71 "T0_3":
"$(T_0)_3$ (s)",
72 "TASC":
"$T_{\\\textrm{asc}}$ (s)",
73 "OM":
"$\\omega_0$ (rad)",
74 "OM_2":
"$(\\omega_0)_2$ (rad)",
75 "OM_3":
"$(\\omega_0)_3$ (rad)",
76 "PBDT":
"$\\dot{P}$ (s/s)",
77 "PBDOT":
"$\\dot{P}$ (s/s)",
83 "FB0":
"$(f_b)_0$ (Hz)",
84 "FB1":
"$(f_b)_1$ (Hz)",
85 "FB2":
"$(f_b)_2$ (Hz)",
86 "FB3":
"$(f_b)_3$ (Hz)",
87 "FB4":
"$(f_b)_4$ (Hz)",
88 "FB5":
"$(f_b)_5$ (Hz)",
89 "FB6":
"$(f_b)_6$ (Hz)",
90 "FB7":
"$(f_b)_7$ (Hz)",
91 "FB8":
"$(f_b)_8$ (Hz)",
92 "FB9":
"$(f_b)_9$ (Hz)",
95 "ELL":
"$\\varepsilon$",
96 "H95":
"$h_0^{95\\%}$",
97 "H0UL":
"$h_0^{{{}\\%}}$",
98 "Q22":
"$Q_{22}$\\,(kg\\,m$^2$)",
99 "SDRAT":
"spin-down ratio",
100 "SDRAT95":
"$h_0^{95\\%}$/h_0^{\\rm sd}$",
101 "SDLIM":
"$h_0^{\\rm sd}$",
102 "F0ROT":
"$f_{\\rm rot}$ (Hz)",
103 "F0GW":
"$f_{\\rm gw}$ (Hz)",
104 "F1ROT":
"$\\dot{f}_{\\rm rot}$ (Hz/s)",
105 "F1GW":
"$\\dot{f}_{\\rm gw}$ (Hz/s)",
106 "SDPOWRAT":
"power ratio (\\%)",
107 "OMDOT":
"$\\dot{\\omega}$",
108 "OMDT":
"$\\dot{\\omega}$",
109 "EPS1":
"$\\epsilon_1$",
110 "EPS2":
"$\\epsilon_2$",
113 "C22UL":
"$C_{{22}}^{{{}\\%}}$",
114 "C21UL":
"$C_{{21}}^{{{}\\%}}$",
115 "PHI22":
"$\\phi_{22}$",
116 "PHI21":
"$\\phi_{21}$",
119 "I31UL":
"$I_{{31}}^{{{}\\%}}$",
120 "I21UL":
"$I_{{21}}^{{{}\\%}}$",
121 "LAMBDA":
"$\\lambda$ (rad)",
122 "COSTHETA":
"$\\cos{\\\theta}$",
123 "DIST":
"distance (kpc)",
125 "BSN":
"$\\log{}_{10}\\left(B_{\\\textrm{SvN}}\\right)$",
126 "BCI":
"$\\log{}_{10}\\left(B_{\\\textrm{CvI}}\\right)$",
127 "BCIN":
"$\\log{}_{10}\\left(B_{\\\textrm{CvIN}}\\right)$",
137 "F0":
"f<sub>0</sub> (Hz)",
138 "F1":
"f<sub>1</sub> (Hz/s)",
139 "F2":
"f<sub>2</sub> (Hz/s<sup>2</sup>)",
140 "F3":
"f<sub>3</sub> (Hz/s<sup>3</sup>)",
141 "F4":
"f<sub>4</sub> (Hz/s<sup>4</sup>)",
142 "F5":
"f<sub>5</sub> (Hz/s<sup>5</sup>)",
143 "F6":
"f<sub>6</sub> (Hz/s<sup>6</sup>)",
144 "F7":
"f<sub>7</sub> (Hz/s<sup>7</sup>)",
145 "F8":
"f<sub>8</sub> (Hz/s<sup>8</sup>)",
146 "F9":
"f<sub>9</sub> (Hz/s<sup>9</sup>)",
147 "F10":
"f<sub>10</sub> (Hz/s<sup>10</sup>)",
148 "F0ROT":
"f<sub>rotation</sub> (Hz)",
149 "F1ROT":
"Spin-down<sub>rotation</sub> (Hz/s)",
150 "F0GW":
"f<sub>GW</sub> (Hz)",
151 "F1GW":
"Spin-down<sub>GW</sub> (Hz/s)",
152 "PEPOCH":
"epoch (MJD)",
153 "A1":
"a sin<it>i</i> (lt s)",
154 "A1_2":
"(a sin<it>i</i>)<sub>2</sub> (lt s)",
155 "A1_3":
"(a sin<it>i</i>)<sub>3</sub> (lt s)",
156 "SINI":
"sin<it>i</it>$",
159 "ECC_2":
"<it>e</it><sub>2</sub>",
160 "ECC_3":
"<it>e</it><sub>3</sub>",
161 "EPS1":
"ε<sub>1</sub>",
162 "EPS2":
"ε<sub>2</sub>",
163 "T0":
"T<sub>0</sub> (MJD)",
164 "T0_2":
"(T<sub>0</sub>)<sub>2</sub> (MJD)",
165 "T0_3":
"(T<sub>0</sub>)<sub>3</sub> (MJD)",
166 "TASC":
"T<sub>asc</sub> (MJD)",
167 "OM":
"ω<sub>0</sub> (deg)",
168 "OM_2":
"(ω<sub>0</sub>)<sub>2</sub> (deg)",
169 "OM_3":
"(ω<sub>0</sub>)<sub>3</sub> (deg)",
170 "M2":
"<it>m</it><sub>2</sub> (kg)",
171 "MTOT":
"<it>M</it> (kg)",
172 "PB":
"<it>P</it><sub>b</sub> (days)",
173 "PB_2":
"(<it>P</it><sub>b</sub>)<sub>2</sub> (days)",
174 "PB_3":
"(<it>P</it><sub>b</sub>)<sub>3</sub> (days)",
175 "FB0":
"(<it>f</it><sub>b</sub>)<sub>0</sub> (Hz)",
176 "FB1":
"(<it>f</it><sub>b</sub>)<sub>1</sub> (Hz)",
177 "FB2":
"(<it>f</it><sub>b</sub>)<sub>2</sub> (Hz)",
178 "FB3":
"(<it>f</it><sub>b</sub>)<sub>3</sub> (Hz)",
179 "FB4":
"(<it>f</it><sub>b</sub>)<sub>4</sub> (Hz)",
180 "FB5":
"(<it>f</it><sub>b</sub>)<sub>5</sub> (Hz)",
181 "FB6":
"(<it>f</it><sub>b</sub>)<sub>6</sub> (Hz)",
182 "FB7":
"(<it>f</it><sub>b</sub>)<sub>7</sub> (Hz)",
183 "FB8":
"(<it>f</it><sub>b</sub>)<sub>8</sub> (Hz)",
184 "FB9":
"(<it>f</it><sub>b</sub>)<sub>9</sub> (Hz)",
185 "H0":
"h<sub>0</sub>",
186 "C21":
"C<sub>21</sub>",
187 "C21UL":
"C<sub>21</sub><sup>{}%</sup>",
188 "C22":
"C<sub>22</sub>",
189 "C22UL":
"C<sub>22</sub><sup>{}%</sup>",
190 "I21":
"I<sub>21</sub>",
191 "I21UL":
"I<sub>21</sub><sup>{}%</sup>",
192 "I31":
"I<sub>31</sub>",
193 "I31UL":
"I<sub>31</sub><sup>{}%</sup>",
194 "COSIOTA":
"cosι",
195 "PSI":
"ψ (rad)",
196 "PHI0":
"φ<sub>0</sub> (rad)",
197 "PHI21":
"φ<sub>21</sub> (rad)",
198 "PHI22":
"φ<sub>22</sub> (rad)",
199 "PMRA":
"p.m. α (rad/s)",
200 "PMDC":
"p.m. δ (rad/s)",
201 "PMDEC":
"p.m. δ (rad/s)",
203 "DIST":
"Distance (kpc)",
204 "SDLIM":
"Spin-down limit",
207 "H95":
"h<sub>0</sub><sup>95%</sup>",
208 "H0UL":
"h<sub>0</sub><sup>{}%</sup>",
209 "H0PRIOR":
"h<sub>0</sub><sup>95%</sup> prior",
210 "SDPOWRAT":
"power ratio (%)",
211 "Q22":
"Q<sub>22</sub> (kg m<sup>2</sup>)",
212 "BSN":
"log<sub>10</sub>(B<sub>SvN</sub>)",
213 "BCI":
"log<sub>10</sub>(B<sub>CvI</sub>)",
214 "BCIN":
"log<sub>10</sub>(B<sub>CvIN</sub>)",
215 "MAXL":
"log<sub>10</sub>(max. L)",
222 return round(x, -
int(math.floor(math.log10(abs(x))) - (sf - 1)))
230 if np.abs(fv) > 0.01
and np.abs(fv) < 1000.0:
232 return repr(round(fv, dp))
234 return "$%s$" % repr(round(fv, dp))
236 return exp_str(fv, dp, otype=horl)
247 def RA(f, stype="hms"):
308 return "%.1f" %
float(
309 repr(44244.0 + (
float(f) + 51.184) / 86400.0)
333 def T0(f, stype=None):
337 return "%.2f" %
float(
338 repr(44244.0 + ((
float(f) + 51.184) / 86400.0))
345 return "%.2f" %
float(
346 repr(44244.0 + ((
float(f) + 51.184) / 86400.0))
351 repr(
float(f) * 180.0 / math.pi), dp=1
415 return "%d" % round(fsf)
418 return "%.1f" %
float(f)
421 return "%d" % round(
float(f))
538 return "%.1f" %
float(f)
547 return "%.2f" %
float(f)
550 return "%.2f" %
float(f)
553 return "%.2f" %
float(f)
606 A class to create
a html
tag
610 self, tag, tagtext="", tagclass="", tagid="", tagstyle="", newline=False
627 '<{tag} class="{class}" id="{id}" style="{style}"{extra}>{text}</{tag}>'
633 Overload the += operator to append text to tagtext
635 if not isinstance(ttext, str)
and not isinstance(ttext, unicode):
636 raise ValueError(
"Error... appended text must be a string.")
646 if not isinstance(t, str)
and not isinstance(t, unicode):
647 raise ValueError(
"Error... 'tag' must be a string.")
656 if not isinstance(tclass, str)
and not isinstance(tclass, unicode):
657 raise ValueError(
"Error... 'class' text must be a string.")
666 if not isinstance(tid, str)
and not isinstance(tid, unicode):
667 raise ValueError(
"Error... 'id' text must be a string.")
676 if not isinstance(tstyle, str)
and not isinstance(tstyle, unicode):
677 raise ValueError(
"Error... 'style' text must be a string.")
686 if not isinstance(ttext, str)
and not isinstance(ttext, unicode):
687 raise ValueError(
"Error... tag text must be a string.")
696 if not isinstance(textra, str)
and not isinstance(textra, unicode):
697 raise ValueError(
"Error... 'extra' tag text must be a string.")
702 self.
_taginfo[
"extra"] = space + textra
722 def __init__(self, link, linktext="", linkclass="", linkid="", linkstyle=""):
724 Input the link and the text that the link surrounds
729 htmltag.__init__(self,
"a", linktext, linkclass, linkid, linkstyle)
735 Class to make and return a html table
738 def __init__(self, tag="table", tableclass="", tableid="", tablestyle=""):
740 self,
"table", tagclass=tableclass, tagid=tableid, tagstyle=tablestyle
750 for row
in self.
_rows:
752 for data
in row[
"data"]:
757 td, data[
"text"], data[
"class"], data[
"id"], data[
"style"]
759 datatag.set_tagextra(
760 'rowspan="{rowspan}" colspan="{colspan}"'.
format(**data)
762 rowtxt += datatag.text +
" "
764 "tr", rowtxt, row[
"class"], row[
"id"], row[
"style"], newline=
True
766 innertable += rowtag.text
770 def addrow(self, rowclass="", rowid="", rowstyle=""):
772 Add a new empty row dictionary to the list and increment the current row index
774 row = {"data": [],
"class": rowclass,
"id": rowid,
"style": rowstyle}
775 self.
_rows.append(row)
783 if rowidx > self.
_nrows - 1:
785 "Warning... cannot delete row '%d'. Only %d row in table."
789 self.
_rows.pop(rowidx)
805 Add table data <td> (or <th>
is header
is True) tags to a given row
810 if rowidx > len(self.
_rows) - 1:
811 raise ValueError(
"Warning... row index is out of range.")
823 td[
"rowspan"] =
str(
int(rowspan))
825 td[
"colspan"] =
str(
int(colspan))
827 self.
_rows[rowidx][
"data"].append(td)
835 Class to make a return a LaTeX table
849 Create a table environment with `ncolumns` columns positioned
with `columnpos`
868 self.
_tableformat =
"\\begin{{table}}{{{floatval}}}\n{preamble}\\caption{{{caption}\\label{{{label}}}}}\n\\begin{{tabular}}{{{columnalign}}}\n{table}\n\\end{{tabular}}\n{postamble}\n\\end{{table}}"
877 if isinstance(columnalign, list):
880 "Error... number of column alignments is not equal to the number of columns."
883 for ca
in columnalign:
884 if not isinstance(ca, str)
and not isinstance(ca, unicode):
886 "Error... columnalign must be a list of strings."
891 if isinstance(columnalign, str)
or isinstance(columnalign, unicode):
892 if len(columnalign) == 1:
897 raise TypeError(
"Error... columnalign must be a list or a string.")
939 row = {
"data": [],
"underline": underline}
940 self.
_rows.append(row)
947 self.
addrow(underline=
True)
949 self.
_rows[rowidx][
"underline"] =
True
951 def adddata(self, datatxt, multicolumn=0, mcalign="c", rowidx=None):
956 if rowidx > len(self.
_rows) - 1:
957 raise ValueError(
"Warning... row index is out of range.")
959 rowdata = {
"text": datatxt}
961 rowdata[
"multicolumn"] = multicolumn
962 rowdata[
"mcalign"] = mcalign
964 self.
_rows[rowidx][
"data"].append(rowdata)
970 for i, row
in enumerate(self.
_rows):
973 for data
in row[
"data"]:
975 if isinstance(val, float)
or isinstance(
979 if "multicolumn" in data:
980 ncols += data[
"multicolumn"]
982 "\\multicolumn{%d}{%s}{%s} "
983 % (data[
"multicolumn"], data[
"mcalign"], val)
987 rowtxt.append(val +
" ")
989 len(rowtxt) != 0
and row[
"underline"] ==
False
991 raise ValueError(
"Error... too many or too few inputs in row '%d'." % i)
993 self.
_tableinfo[
"table"] +=
"&".join(rowtxt) +
"\\\n"
1004 print(
"Precision must be less than 16 d.p.", file=sys.stderr)
1008 ssplit = s.split(
"e")
1009 if otype.lower() ==
"html":
1010 return "%.*f×10<sup>%d</sup>" % (p,
float(ssplit[0]),
int(ssplit[1]))
1011 elif otype.lower() ==
"latex":
1012 return "\\ensuremath{%.*f\\!\\times\\!10^{%d}}" % (
1018 raise ValueError(
"Error... 'otype' must be 'html' or 'latex'.")
1023 if isinstance(ra, str):
1025 elif isinstance(ra, float):
1028 raise ValueError(
"Error... ra must be a string or a float.")
1036 ss = (
"%.2f" %
float(hms[2])).split(
".")
1038 if otype.lower() ==
"html":
1039 return "%s<sup>h</sup>%s<sup>m</sup>%s<sup>s</sup>.%s" % (
1045 elif otype.lower() ==
"latex":
1046 return "$%s^{\\rm h}%s^{\\rm m}%s^{\\rm s}\\!.%s$" % (
1053 raise ValueError(
"Error... 'otype' input must be 'html' or 'latex'")
1058 if isinstance(dec, str):
1059 dms = dec.split(
":")
1060 elif isinstance(dec, float):
1063 raise ValueError(
"Error... dec must be a string or a float.")
1071 ss = (
"%.2f" %
float(dms[2])).split(
".")
1073 if otype.lower() ==
"html":
1074 return "%s°%s'%s\".%s" % (
1075 (re.sub(
r"\+",
"", dms[0])).zfill(2),
1080 elif otype.lower() ==
"latex":
1081 return "$%s^{\\circ}%s'%s''\\!.%s$" % (
1082 (re.sub(
r"\+",
"", dms[0])).zfill(2),
1088 raise ValueError(
"Error... 'otype' must be 'html' or 'latex'.")
1092CSS files for results pages
1096result_page_css =
"""
1097/* create body style */
1099 font-family: "Avant Garde", Avantegarde, Verdana, Geneva,
"Trebuchet MS", sans-serif;
1102/* create header name style */
1104 margin: 0px 0px 0px 0px;
1105 padding: 4px 4px 8px 4px;
1108 letter-spacing: 0px;
1109 font-family:
"Avant Garde", Avantegarde, Verdana, Geneva,
"Trebuchet MS", Sans-Serif;
1110 background-color: darkolivegreen;
1115 text-shadow: 2px 2px 2px
1116 text-decoration: none;
1121 text-shadow: 2px 2px 2px
1122 text-decoration: none;
1127 text-shadow: 2px 2px 2px
1128 text-decoration: none;
1133 padding: 4px 4px 8px 4px;
1136 font-family:
"Avant Garde", Avantegarde, Verdana, Geneva,
"Trebuchet MS", Sans-Serif;
1137 text-shadow: 1px 1px 1px
1142/* create footer style */
1144 border-top: 1px solid
1146 font-family: monospace;
1150/* create a
class for
a posterior
plot image */
1156/* create a
class for
a full joint posterior
plot image */
1162/* create a
class for
a background distribution
plot image */
1173/* create
class for an amplitude spectral density
plot */
1178/* create
class for an MCMC chain
plot */
1183/* style
for links list */
1185 background-color: darkolivegreen;
1186 font-family:
"Avant Garde", Avantegarde, Verdana, Geneva,
"Trebuchet MS", Sans-Serif;
1190 padding: 0px 0px 3px 3px;
1191 margin: 0px 0px 8px 0px;
1192 text-shadow: 2px 2px 2px
1195div.pagelinks a:link {
1197 text-shadow: 2px 2px 2px
1198 text-decoration: none;
1201div.pagelinks a:visited {
1203 text-shadow: 2px 2px 2px
1204 text-decoration: none;
1207div.pagelinks a:hover {
1209 text-shadow: 2px 2px 2px
1210 text-decoration: none;
1213/* pulsar parameter table
class */
1215 background-color: floralwhite;
1218 box-shadow: 2px 2px 2px 2px
1219 -webkit-box-shadow: 2px 2px 2px 2px
1220 -moz-box-shadow: 2px 2px 2px 2px
1221 padding: 4px 4px 4px 4px;
1224/* upper limits table
class */
1226 background-color: floralwhite;
1229 box-shadow: 2px 2px 2px 2px
1230 -webkit-box-shadow: 2px 2px 2px 2px
1231 -moz-box-shadow: 2px 2px 2px 2px
1232 padding: 4px 4px 4px 4px;
1235/* background evidence table
class */
1237 background-color: floralwhite;
1240 box-shadow: 2px 2px 2px 2px
1241 -webkit-box-shadow: 2px 2px 2px 2px
1242 -moz-box-shadow: 2px 2px 2px 2px
1243 padding: 4px 4px 4px 4px;
1246/* set defaults
for table data
and table headers */
1249 border-collapse: collapse;
1253 padding: 0px 8px 0px 8px;
1258 padding: 0px 8px 0px 8px;
1263 border-left: 1px solid
1267 border-right: 1px solid
1271 border-top: 1px solid
1275 border-bottom: 1px solid
1278/* set text colour classes
for detectors */
1306# create css file text for the tables of all results
1307results_table_css = """
1308/* create body style */
1310 font-family: Verdana, Geneva,
"Trebuchet MS", sans-serif;
1313/* create footer style */
1315 border-top: 1px solid
1317 font-family: monospace;
1321/* create link style */
1324 text-decoration: none;
1329 text-decoration: none;
1334 text-decoration: none;
1335 text-shadow: 2px 2px 2px
1338/* set defaults
for table data
and table headers */
1341 border-collapse: collapse;
1345 padding: 0px 8px 0px 8px;
1350 padding: 0px 8px 0px 8px;
1355 border-left: 1px solid
1359 border-right: 1px solid
1363 border-top: 1px solid
1367 border-bottom: 1px solid
1370/* set text colour classes
for detectors */
def __init__(self, link, linktext="", linkclass="", linkid="", linkstyle="")
Input the link and the text that the link surrounds.
Class to make and return a html table.
def addrow(self, rowclass="", rowid="", rowstyle="")
Add a new empty row dictionary to the list and increment the current row index.
def __init__(self, tag="table", tableclass="", tableid="", tablestyle="")
def deleterow(self, rowidx)
Delete a row.
def adddata(self, datatext, dataclass="", dataid="", datastyle="", header=False, rowspan=0, colspan=0, rowidx=None)
Add table data (or is header is True) tags to a given row.
A class to create a html tag.
def set_tagstyle(self, tstyle)
def __init__(self, tag, tagtext="", tagclass="", tagid="", tagstyle="", newline=False)
def set_tagextra(self, textra)
def set_tagclass(self, tclass)
def set_tagtext(self, ttext)
def __iadd__(self, ttext)
Overload the += operator to append text to tagtext.
Class to make a return a LaTeX table.
def set_label(self, label)
def set_preamble(self, preamble)
def set_ncolumns(self, ncolumns)
def adddata(self, datatxt, multicolumn=0, mcalign="c", rowidx=None)
def addrow(self, underline=False)
def __init__(self, ncolumns=1, columnalign="c", caption="", label="", floatval="h", preamble="", postamble="")
Create a table environment with ncolumns columns positioned with columnpos
def set_caption(self, caption)
def set_floatval(self, floatval)
def addhrule(self, rowidx=None)
def set_postamble(self, postamble)
def set_columnalign(self, columnalign)
def dec_str(dec, otype="html")
def dec_or_exp(f, dp=2, horl="html")
def ra_str(ra, otype="html")
def exp_str(f, p=1, otype="html")
def rad_to_hms(rad)
rad_to_hms(rad): Convert radians to hours, minutes, and seconds of arc.
def rad_to_dms(rad)
rad_to_dms(rad): Convert radians to degrees, minutes, and seconds of arc.