25 from __future__
import print_function, division
28 from six.moves.configparser
import ConfigParser
39 from scipy
import stats
50 from lalinference
import git_version
52 __author__ =
"Matthew Pitkin <matthew.pitkin@ligo.org>"
53 __version__ =
"git id %s" % git_version.id
54 __date__ = git_version.date
58 from scotchcorner
import scotchcorner
61 "Could no import scotchcorner: make sure scotchcorner is installed (e.g. 'pip install scotchcorner') and in the PYTHONPATH",
72 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
73 <meta name="description" content="PSR {psrname}"/>
74 <meta charset="UTF-8">
76 <title>{title}</title>
78 <link rel="stylesheet" type="text/css" href="{cssfile}"/>
84 <!- add in javascript to allow text toggling -->
85 <script language="javascript">
86 function toggle(id) {{
87 var ele = document.getElementById(id);
88 if(ele.style.display == "block"){{
89 ele.style.display = "none";
92 ele.style.display = "block";
99 <!-- Links to the parts of the page -->
100 <div class="pagelinks">
104 <!-- table of pulsar parameters from EM data -->
108 <div class="pulsartable" id="pulsartable">
114 <!-- table of derived gravitational wave upper limits, SNRs and evidence ratios -->
115 <div class="limitstable" id="limitstable">
124 <!-- plots of 1D and 2D marginalised posteriors for GW amplitude and phase parameters -->
125 <div class="selectedposteriors" id="selectedposteriors">
131 <!-- corner plot of all parameters (hidden by default) -->
132 <div class="jointposteriors" id="jointposteriors">
138 <!-- (if background runs have been produced): if running a multi-detector analysis the plot
139 coherent vs. incoherent Bayes factors (with SNR giving colour of points) of background
140 and foreground, or if single detector plot signal vs. noise Bayes factor against SNR. -->
141 <div class="evidenceplots" id="evidenceplots">
147 <!-- plots of pre-processed data (heterodyned/spectrally interpolated time series) -->
148 <div class="dataplots" id="dataplots">
154 <!-- plots of the posterior samples for all parameters -->
155 <div class="posteriorsamples" id="posteriorsamples">
161 <!-- table of posterior statistics: means, max. likelihoods, confidence intervals -->
162 <div class="posteriorstats" id="posteriorstats">
180 Set the spin-down of the source based on the intrinsic period derivative (p1_I) corrected for any proper motion/
181 globular cluster acceleration if available, or if not give AND the pulsar is in a globular cluster base the
182 spin-down on assuming an age of 10^9 years (defaulting to the source being a gravitar, with n=5).
183 Otherwise just return the unadjusted spin-down.
186 if p1_I !=
None and p1_I > 0.0:
190 return -f0 / ((n - 1.0) * 1.0e9 * 365.25 * 86400.0)
199 Create a html table of some information from the pulsar parameter file.
221 for param
in paramdisplist:
225 dispfunc = paramhtmldispfunc.__dict__[param]
226 table.adddata(paramhtmldict[param])
227 table.adddata(dispfunc(
str(pa)))
229 return table.tabletext
234 self, datafiles, outputdir, figformats=["png"], asdtime=86400, harmonics=[2.0]
237 Initialise with a dictionary keyed in detector names containing paths to the equivalent pre-processed
238 data file(s) for that detector (if harmonics contains more than one frequency harmonic this there should
239 be a list of files, with one for each harmonic and given in the same order as the harmonics lists).
240 figformats gives a list of the output figure formats (defaulting to .png), and asd time is the time to use
241 for each FFT when creating the spectrograms/ASDs, which defaults to 86400 seconds (1 day).
245 "h2",
"Analysis statistics", newline=
True
248 if not isinstance(harmonics, list):
253 self.
_ifos_ifos = list(datafiles.keys())
258 for i, ifo
in enumerate(datafiles):
259 if isinstance(datafiles[ifo], list):
260 if len(datafiles[ifo]) != self.
_nharmonics_nharmonics:
262 "Error... number of pre-processed data files is not the same as the number of harmonics.",
271 for j, df
in enumerate(datafiles[ifo]):
272 if not os.path.isfile(df):
274 "Error... pre-processed data file '%s' for '%s' does not exist."
285 if not os.path.isfile(df):
287 "Error... pre-processed data file '%s' for '%s' does not exist."
295 "Error... number of pre-processed data files is not the same as the number of harmonics.",
301 if not os.path.isdir(self.
_outputdir_outputdir):
303 "Error... output path '%s' for data plots does not exist"
310 if "png" not in figformats:
312 "Error... must include 'png' in the output figure formats",
344 self.
_asds_asds[h] = {}
357 harmtext =
"_%d" %
int(h)
360 for i, ifo
in enumerate(self.
_ifos_ifos):
361 self.
_asds_asds[h][ifo] = asdlist[
366 for fig, fignameprefix
in zip(
367 [Bkfigs[i], fscanfigs[i], asdfigs[i]], [
"Bk",
"fscan",
"ASD"]
370 figname = os.path.join(
371 outdir,
"%s_%s%s.%s" % (fignameprefix, ifo, harmtext, ftype)
377 "Error... problem creating figure '%s'." % figname,
383 self.
_Bkplots_Bkplots[h][ifo] = os.path.join(
384 outdir,
"Bk_%s%s.%s" % (ifo, harmtext, ftype)
386 self.
_asdplots_asdplots[h][ifo] = os.path.join(
387 outdir,
"ASD_%s%s.%s" % (ifo, harmtext, ftype)
389 self.
_fscanplots_fscanplots[h][ifo] = os.path.join(
390 outdir,
"fscan_%s%s.%s" % (ifo, harmtext, ftype)
411 return self.
_asds_asds
415 for i, ifo
in enumerate(self.
_ifos_ifos):
423 "Error... could not load file '%s'."
429 self.
_starts_starts[ifo] = bkd[0, 0]
430 self.
_ends_ends[ifo] = bkd[-1, 0]
431 dt = np.min(np.diff(bkd[:, 0]))
432 self.
_length_length[ifo] = float(len(bkd)) * dt
441 table.adddata(
" ")
442 table.adddata(ifo, dataclass=ifo)
447 (
"Duty factor (%)",
"%.lf" % self.
_duty_factor_duty_factor[ifo]),
451 table.adddata(item[0])
452 table.adddata(item[1])
454 return table.tabletext
459 for ifo
in self.
_ifos_ifos:
463 table.adddata(
"Data for %df" %
int(h), colspan=2, header=
True)
470 os.path.basename(self.
_Bkplots_Bkplots[h][ifo]),
471 '<img class="dataplot" src="{}"/>'.format(
472 os.path.basename(self.
_Bkplots_Bkplots[h][ifo])
475 table.adddata(plotlink)
478 os.path.basename(self.
_asdplots_asdplots[h][ifo]),
479 '<img class="asdplot" src="{}"/>'.format(
480 os.path.basename(self.
_asdplots_asdplots[h][ifo])
483 table.adddata(plotlink)
485 os.path.basename(self.
_fscanplots_fscanplots[h][ifo]),
486 '<img class="dataplot" src="{}"/>'.format(
487 os.path.basename(self.
_fscanplots_fscanplots[h][ifo])
490 table.adddata(plotlink)
500 Get sample posteriors and created a set of functions for outputting tables, plots and posterior statistics
509 modeltype="waveform",
514 subtracttruths=False,
518 Initialise with a dictionary keyed in detector names containing paths to the equivalent posterior samples
519 file for that detector.
522 if not os.path.isdir(self.
_outputdir_outputdir):
524 "Error... output path '%s' for data plots does not exist"
531 self.
_ifos_ifos = list(postfiles.keys())
533 if isinstance(ifos, list):
534 self.
_ifos_ifos = ifos
536 self.
_ifos_ifos = [ifos]
538 for ifo
in self.
_ifos_ifos:
539 if ifo
not in postfiles:
541 "Error... posterior files for detector '%s' not given" % ifo,
556 self.
_Bcin_Bcin =
None
578 if self.
_parfile_parfile
is not None:
584 "Error... cannot read injection parameter file '%s'."
617 if "Joint" in self.
_ifos_ifos:
618 j = self.
_ifos_ifos.pop(self.
_ifos_ifos.index(
"Joint"))
619 self.
_ifos_ifos.append(j)
628 "Error... cannot read prior file '%s'." % self.
_priorfile_priorfile,
633 for line
in pf.readlines():
634 priorlinevals = line.split()
635 if len(priorlinevals) < 4:
637 "Error... there must be at least four values on each line of the prior file '%s'."
643 if priorlinevals[1]
not in [
651 "Error... the prior for '%s' must be either 'uniform', 'loguniform', 'gmm', 'fermidirac', or 'gaussian'."
657 if priorlinevals[1]
in [
663 if len(priorlinevals) != 4:
665 "Error... there must be four values on each line of the prior file '%s'."
671 [float(priorlinevals[2]), float(priorlinevals[3])]
675 self.
_usegwphase_usegwphase
and priorlinevals[0].lower() ==
"phi0"
677 ranges = 2.0 * ranges
678 elif priorlinevals[1] ==
"gmm":
681 ranges[
"nmodes"] = priorlinevals[2]
682 ranges[
"means"] = ast.literal_eval(priorlinevals[3])
683 ranges[
"covs"] = ast.literal_eval(
686 ranges[
"weights"] = ast.literal_eval(
691 p.lower()
for p
in priorlinevals[0].split(
":")
693 npars = len(splitpars)
694 for lims
in priorlinevals[6:-1]:
695 plims.append(np.array(ast.literal_eval(lims)))
696 ranges[
"limits"] = plims
697 ranges[
"npars"] = npars
698 if self.
_usegwphase_usegwphase
and "phi0" in splitpars:
699 phi0idx = splitpars.index(
"phi0")
701 for ci
in range(ranges[
"nmodes"]):
702 ranges[
"means"][ci][phi0idx] = (
703 2.0 * ranges[
"means"][ci][phi0idx]
708 ranges[
"covs"][ci][phi0idx][ck] = (
709 2.0 * ranges[
"covs"][ci][phi0idx][ck]
711 ranges[
"covs"][ci][ck][phi0idx] = (
712 2.0 * ranges[
"covs"][ci][ck][phi0idx]
714 ranges[
"limits"][phi0idx] = 2.0 * ranges[
"limits"][phi0idx]
715 for sidx, spar
in enumerate(splitpars):
716 ranges[
"pindex"] = sidx
723 self.
_prior_parameters_prior_parameters[priorlinevals[0]] = {priorlinevals[1]: ranges}
726 for ifo
in postfiles:
727 if not os.path.isfile(postfiles[ifo]):
729 "Error... posterior samples file '%s' for '%s' does not exist."
730 % (postfiles[ifo], ifo),
739 self.
_Bsn_Bsn[ifo] = sigev - noiseev
742 for param
in pos.names:
745 for testpar
in [
"logl",
"logw",
"logprior"]:
746 if testpar
in param.lower():
750 theseparams.append(param)
753 self.
_parameters_parameters = copy.copy(theseparams)
755 for param
in theseparams:
758 "Error... parameter '%s' is not defined in posteriors samples for '%s'."
765 if modeltype ==
"source":
768 if "phi0" in pos.names:
769 phi0samples = pos[
"phi0"].samples
770 if "psi" in pos.names:
771 psisamples = pos[
"psi"].samples
774 if psisamples
is not None:
775 for i
in range(len(psisamples)):
777 np.floor(psisamples[i] / (np.pi / 2.0))
779 psisamples[i] = np.mod(psisamples[i], np.pi / 2.0)
780 if phi0samples
is not None:
781 phi0samples[i] += nrots * (np.pi / 2.0)
787 if phi0samples
is not None:
788 phi0samples = np.mod(phi0samples, np.pi)
796 if "phi0" in pos.names:
804 if "c22" in pos.names
and self.
_modeltype_modeltype ==
"waveform":
811 if self.
_parfile_parfile
is not None:
819 if "phi22" in pos.names
and modeltype ==
"waveform":
821 "phi0", 0.5 * pos[
"phi22"].samples
828 if self.
_parfile_parfile
is not None:
844 if "phi21" in pos.names:
846 "phi22", 2.0 * pos[
"phi21"].samples
849 if self.
_parfile_parfile
is not None:
886 return self.
_Bcin_Bcin
890 if ifo
in self.
_h0ul_h0ul:
891 return self.
_h0ul_h0ul[ifo]
904 if ifo
in self.
_q22_q22:
905 return self.
_q22_q22[ifo]
911 if ifo
in self.
_C21_C21:
912 return self.
_C21_C21[ifo]
918 if ifo
in self.
_C22_C22:
919 return self.
_C22_C22[ifo]
925 if ifo
in self.
_I21_I21:
926 return self.
_I21_I21[ifo]
932 if ifo
in self.
_I31_I31:
933 return self.
_I31_I31[ifo]
946 for ifo
in self.
_ifos_ifos:
948 os.path.dirname(self.
_postfiles_postfiles[ifo])
955 snrfiles = [sf
for sf
in os.listdir(pdir)
if "SNR" in sf]
956 if len(snrfiles) < 1:
957 print(
"Error... no SNR files are given for '%s'" % ifo, file=sys.stderr)
965 fp = open(os.path.join(pdir, snrfile),
"r")
966 lines = [line.strip()
for line
in fp.readlines()]
968 if "# Recovered SNR" not in lines:
970 "Error... no recovered SNRs are given in the SNR file '%s'."
977 linevals = lines[-1].split()
978 snr += float(linevals[-1])
979 return snr / len(snrfiles)
981 def _get_bayes_factors(self):
985 for ifo
in self.
_ifos_ifos:
990 self.
_maxL_maxL[ifo],
1001 list(i)
for i
in itertools.product([
"s",
"n"], repeat=nifos)
1003 incoherentcombs = -np.inf
1007 if comb.count(
"n") != len(
1011 for i, cval
in enumerate(comb):
1012 combsum += ifosn[i][cval]
1013 incoherentcombs = np.logaddexp(incoherentcombs, combsum)
1014 if comb.count(
"s") == len(comb):
1015 incoherentsig = combsum
1018 if len(self.
_ifos_ifos) > 2
and "Joint" in self.
_ifos_ifos:
1027 fe = os.path.splitext(postfile)[-1].lower()
1028 if fe ==
".h5" or fe ==
".hdf":
1030 f = h5py.File(postfile,
"r")
1031 a = f[
"lalinference"][
"lalinference_nest"]
1033 a.attrs[
"log_bayes_factor"],
1034 a.attrs[
"log_evidence"],
1035 a.attrs[
"log_noise_evidence"],
1036 a.attrs[
"log_max_likelihood"],
1040 B = np.loadtxt(postfile.replace(
".gz",
"") +
"_B.txt")
1041 evdata = tuple(B.tolist())
1044 "Error... could not extract evidences from '%s'." % postfile,
1066 credintervals=[0.9],
1077 if ifo !=
None and ifo
in self.
_ifos_ifos:
1080 plotifos = self.
_ifos_ifos
1083 if "Joint" in plotifos:
1084 j = plotifos.pop(plotifos.index(
"Joint"))
1085 plotifos.insert(0, j)
1096 if len(parameters) < 2
or len(parameters) > len(self.
_parameters_parameters):
1098 "Error... can only plot posterior distributions for more than one parameters",
1104 for param
in parameters:
1107 "Error... the requested parameter '%s' is not recognised" % param,
1120 if truths
is not None:
1121 if isinstance(truths, list):
1123 if len(truths) != len(parameters):
1125 "Error... number of true values must be the same as number of parameters.",
1131 for ifo
in plotifos:
1132 newtruths[ifo] = truths
1137 for ifo
in plotifos:
1138 if ifo
not in truths:
1140 "Error... problem in truths values. Detector '%s' not recognised."
1146 if len(truths[ifo]) != len(parameters):
1148 "Error... number of true values must be the same as number of parameters.",
1154 for ifo
in plotifos:
1158 subtract_truths = []
1175 if truths
is not None and self.
_subtract_truths_subtract_truths
is not None:
1176 if parameters[0]
not in amppars:
1177 subtract_truths.append(0)
1180 x = self.
_posteriors_posteriors[plotifos[0]][parameters[0]].samples
1182 if parameters[0].upper()
in paramlatexdict:
1183 labels.append(paramlatexdict[parameters[0].upper()])
1185 labels.append(parameters[0])
1186 for param
in parameters[1:]:
1187 x = np.hstack((x, self.
_posteriors_posteriors[plotifos[0]][param].samples))
1188 if param.upper()
in paramlatexdict:
1189 labels.append(paramlatexdict[param.upper()])
1191 labels.append(param)
1192 if truths
is not None and self.
_subtract_truths_subtract_truths
is not None:
1193 if param
not in amppars:
1194 subtract_truths.append(parameters.index(param))
1196 if len(subtract_truths) == 0:
1197 subtract_truths =
None
1200 if plotifos[0] ==
"Joint":
1202 "histtype":
"stepfilled",
1203 "color":
"darkslategrey",
1204 "edgecolor": coldict[
"Joint"],
1207 contourops = {
"colors": coldict[plotifos[0]]}
1209 if whichtruth ==
"Joint" or whichtruth ==
"all":
1210 truthops = {
"color":
"black",
"markeredgewidth": 2}
1213 showpoints = jointsamples
1216 contourops = {
"colors":
"dark" + coldict[plotifos[0]]}
1218 if len(plotifos) == 1:
1220 "histtype":
"stepfilled",
1221 "color": coldict[plotifos[0]],
1222 "edgecolor": coldict[plotifos[0]],
1225 truthops = {
"color":
"black",
"markeredgewidth": 2}
1229 "color": coldict[plotifos[0]],
1230 "edgecolor": coldict[plotifos[0]],
1233 if whichtruth == plotifos[0]:
1234 truthops = {
"color":
"black",
"markeredgewidth": 2}
1235 elif whichtruth ==
"all":
1237 "color":
"dark" + coldict[plotifos[0]],
1238 "markeredgewidth": 2,
1248 truths=truths[plotifos[0]],
1249 datatitle=plotifos[0],
1251 hist_kwargs=histops,
1252 showcontours=showcontours,
1253 contour_levels=credintervals,
1254 contour_kwargs=contourops,
1255 truths_kwargs=truthops,
1256 contour_limits=contourlimits,
1258 show_level_labels=
False,
1259 showpoints=showpoints,
1260 scatter_kwargs=scatter_kwargs,
1261 subtract_truths=subtract_truths,
1265 if len(plotifos) > 1:
1266 for k, ifo
in enumerate(plotifos[1:]):
1269 "color": coldict[ifo],
1270 "edgecolor": coldict[ifo],
1273 x = self.
_posteriors_posteriors[ifo][parameters[0]].samples
1274 for param
in parameters[1:]:
1275 x = np.hstack((x, self.
_posteriors_posteriors[ifo][param].samples))
1277 contourops = {
"colors":
"dark" + coldict[plotifos[k + 1]]}
1278 if whichtruth == plotifos[k + 1]:
1279 truthops = {
"color":
"black",
"markeredgewidth": 2}
1280 elif whichtruth ==
"all":
1282 "color":
"dark" + coldict[plotifos[k + 1]],
1283 "markeredgewidth": 2,
1289 hist_kwargs=histops,
1292 showcontours=showcontours,
1293 contour_kwargs=contourops,
1294 contour_levels=credintervals,
1295 show_level_labels=
False,
1296 truths_kwargs=truthops,
1297 scatter_kwargs=scatter_kwargs,
1298 contour_limits=contourlimits,
1305 if priorparam.lower()
in parameters:
1307 thisax = sc.get_axis(labels[parameters.index(priorparam.lower())])
1313 and priorparam.lower()
not in amppars
1315 atruth = truths[plotifos[0]][
1316 parameters.index(priorparam.lower())
1320 vertaxrange = sc.histvert[-1].get_ylim()
1321 yl = thisax.get_ylim()
1323 yl[0] == vertaxrange[0]
and yl[1] == vertaxrange[1]
1330 orientation=
"vertical",
1338 orientation=
"horizontal",
1342 if "png" not in figformats
and "svg" not in figformats:
1344 "Error... must include 'png' and/or 'svg' in the output figure formats",
1349 if filename ==
None:
1350 if len(parameters) == len(self.
_parameters_parameters):
1351 outfilepre = os.path.join(self.
_outputdir_outputdir,
"all_posteriors")
1353 outfilepre = os.path.join(self.
_outputdir_outputdir,
"vs".join(parameters))
1355 outfilepre = os.path.join(self.
_outputdir_outputdir, filename)
1358 for ftype
in figformats:
1359 outfile = outfilepre +
"." + ftype
1361 sc.fig.subplots_adjust(
1362 left=0.18, bottom=0.18
1367 "Error... could not output posterior plot file '%s'." % outfile,
1371 outfiles.append(outfile)
1376 self, ax, param, prior, orientation="horizontal", truth=0.0, npoints=100
1379 priortype = list(prior[param].keys())[0]
1380 priorrange = list(prior[param].values())[0]
1385 if orientation ==
"horizontal":
1386 valrange = np.linspace(ax.get_xlim()[0], ax.get_xlim()[1], npoints)
1387 elif orientation ==
"vertical":
1388 valrange = np.linspace(ax.get_ylim()[0], ax.get_ylim()[1], npoints)
1391 "Error... axis orientation not recognised. Must be 'horizontal' or 'vertical'.",
1397 if priortype ==
"uniform":
1398 vals = stats.uniform.pdf(
1399 valrange, priorrange[0] - truth, priorrange[1] - priorrange[0]
1401 elif priortype ==
"gaussian":
1403 if param.lower() ==
"psi":
1404 priorrange[0] = np.mod(priorrange[0], np.pi / 2.0)
1405 if param.lower() ==
"phi0":
1407 priorrange[0] = np.mod(priorrange[0], 2.0 * pi)
1409 priorrange[0] = np.mod(priorrange[0], pi)
1411 vals = stats.norm.pdf(valrange, priorrange[0] - truth, priorrange[1])
1413 priortype ==
"fermidirac"
1415 sigma = priorrange[0]
1419 (sigma * np.log(1.0 + np.exp(r)))
1420 * (np.exp((valrange - mu) / sigma) + 1.0)
1422 elif priortype ==
"loguniform":
1423 vals = np.zeros(len(valrange))
1424 indices = (valrange >= priorrange[0]) & (valrange <= priorrange[1])
1425 vals[indices] = 1.0 / (
1426 valrange[indices] * np.log(priorrange[1] / priorrange[0])
1428 elif priortype ==
"gmm":
1429 vals = np.zeros(len(valrange))
1430 nmodes = priorrange[
"nmodes"]
1431 pindex = priorrange[
"pindex"]
1432 mmeans = np.array([mm[pindex]
for mm
in priorrange[
"means"]])
1433 mcovs = priorrange[
"covs"]
1436 mstddevs.append(np.sqrt(cov[pindex][pindex]))
1437 mweights = priorrange[
"weights"]
1441 plims = priorrange[
"limits"][pindex]
1442 if np.isfinite(plims[0]):
1444 if np.isfinite(plims[1]):
1446 indices = (valrange >= bmin) & (valrange <= bmax)
1449 if param.lower() ==
"psi":
1450 mmeans = np.mod(mmeans, np.pi / 2.0)
1451 if param.lower() ==
"phi0":
1453 mmeans = np.mod(mmeans, 2.0 * pi)
1455 mmeans = np.mod(mmeans, pi)
1458 for i
in range(nmodes):
1459 vals[indices] += mweights[i] * stats.norm.pdf(
1460 valrange[indices], mmeans[i] - truth, mstddevs[i]
1463 vals = vals / np.trapz(vals, valrange)
1466 "Error... prior type '%s' not recognised." % priortype, file=sys.stderr
1471 if orientation ==
"horizontal":
1473 valrange, vals, linestyle=
"--", color=
"lightslategray", linewidth=1.5
1475 if orientation ==
"vertical":
1477 vals, valrange, linestyle=
"--", color=
"lightslategray", linewidth=1.5
1483 header =
htmltag(
"h2", title, newline=
True)
1495 for ifo
in self.
_ifos_ifos:
1498 - 3.0 * self.
_posteriors_posteriors[ifo][param].stdev
1501 limits[param] = (0.0,
None)
1503 elif param ==
"cosiota":
1504 limits[param] = (-1.0, 1.0)
1505 elif param ==
"phi0":
1507 limits[param] = (0.0, 2.0 * np.pi)
1509 limits[param] = (0.0, np.pi)
1510 elif param ==
"psi":
1512 limits[param] = (0.0, np.pi)
1514 limits[param] = (0.0, np.pi / 2.0)
1515 elif param ==
"c21" or param ==
"c22":
1520 for ifo
in self.
_ifos_ifos:
1523 - 3.0 * self.
_posteriors_posteriors[ifo][param].stdev
1526 limits[param] = (0.0,
None)
1528 elif param ==
"lambda":
1529 limits[param] = (0.0, np.pi)
1530 elif param ==
"costheta":
1531 limits[param] = (0.0, 1.0)
1539 if harmonics[0] == 2.0:
1541 paramlist = [[
"h0",
"cosiota"], [
"phi0",
"psi"]]
1545 "Error... do not know 'source' parameterisation for emission at purely the rotation frequency",
1551 paramlist = [[
"c21",
"cosiota"], [
"phi21",
"psi"]]
1557 [
"i31",
"cosiota",
"phi0"],
1558 [
"psi",
"lambda",
"costheta"],
1563 [
"i21",
"i31",
"cosiota"],
1564 [
"phi0",
"psi",
"lambda",
"costheta"],
1568 paramlist = [[
"c21",
"c22",
"cosiota"], [
"psi",
"phi21",
"phi22"]]
1571 for parampairs
in paramlist:
1574 for p
in parampairs:
1578 contourlimits.append(limits[p])
1579 figlimits.append(limits[p])
1587 figlimits=figlimits,
1588 contourlimits=contourlimits,
1592 tagclass =
"jointplot"
1594 tagclass =
"posplot"
1597 os.path.basename(pf[0]),
1598 '<img class="{}" src="{}"/>'.format(
1599 tagclass, os.path.basename(pf[0])
1604 return header.text + table.tabletext
1608 if "png" not in figformats:
1610 "Error... must include 'png' in the output figure formats",
1616 "h2",
"Posterior samples", newline=
True
1626 chainfile = os.path.join(self.
_outputdir_outputdir, param +
"_postchain")
1628 for ftype
in figformats:
1629 thischainfile = chainfile +
"." + ftype
1631 chainfig.savefig(thischainfile)
1634 "Error... could not output posterior samples plot for '%s'."
1644 os.path.basename(thischainfile),
1645 '<img class="chainplot" src="{}"/>'.format(
1646 os.path.basename(thischainfile)
1651 self.
_samples_table_samples_table = header.text + table.tabletext
1658 if ci >= 100.0
or ci <= 0.0:
1660 "Error... credible interval '%s' is outside the range between 0%% and 100%%."
1666 header =
htmltag(
"h2",
"Posterior statistics", newline=
True)
1670 cols = [
"Detector",
"max. poterior",
"mean",
"median",
"σ"]
1672 cols.append(
"%d%% credible interval" %
int(ci))
1674 cols.insert(0,
"Inj. value")
1675 cols.insert(0,
" ")
1680 table.adddata(col, header=
True)
1683 for i, param
in enumerate(self.
_parameters_parameters):
1690 if pu
in paramhtmldict:
1691 pdisp = paramhtmldict[pu]
1694 if pu
in [
"RA",
"DEC",
"RAJ",
"DECJ"]:
1699 dispkwargs = {
"dp": 2}
1704 if pu
in paramhtmldispfunc.__dict__:
1705 dispfunc = paramhtmldispfunc.__dict__[pu]
1707 dispfunc = paramhtmldispfunc.__dict__[
"DEFAULTSTR"]
1709 for j, ifo
in enumerate(self.
_ifos_ifos):
1712 table.adddata(pdisp, rowspan=len(self.
_ifos_ifos))
1720 rowspan=len(self.
_ifos_ifos),
1724 "*", rowspan=len(self.
_ifos_ifos)
1733 maxL, maxLparams = self.
_posteriors_posteriors[ifo].maxL
1734 table.adddata(ifo, dataclass=ifo)
1736 dispfunc(
str(maxLparams[param]), **dispkwargs)
1739 dispfunc(
str(self.
_posteriors_posteriors[ifo].means[param]), **dispkwargs)
1742 dispfunc(
str(self.
_posteriors_posteriors[ifo].medians[param]), **dispkwargs)
1744 tdispkwargs = dispkwargs
1745 if param.upper()
in [
"T0",
"TASC"]:
1746 tdispkwargs = {
"stype":
"diff"}
1748 dispfunc(
str(self.
_posteriors_posteriors[ifo].stdevs[param]), **tdispkwargs)
1751 for k, ci
in enumerate(credints):
1756 low, high, cr = self.
credible_intervalcredible_interval(ifo, param, ci, paramval)
1764 dispfunc(
str(low), **dispkwargs),
1765 dispfunc(
str(high), **dispkwargs),
1769 self.
_stats_section_stats_section = header.text + table.tabletext
1778 self.
_h0ul_h0ul = {}
1790 table.adddata(
" ", header=
True)
1793 table.adddata(paramhtmldict[
"H0UL"].format(ul), header=
True)
1794 table.adddata(paramhtmldict[
"ELL"], header=
True)
1795 table.adddata(paramhtmldict[
"Q22"], header=
True)
1796 table.adddata(paramhtmldict[
"SDRAT"], header=
True)
1802 table.adddata(paramhtmldict[
"C21UL"].format(ul), header=
True)
1804 table.adddata(paramhtmldict[
"C21UL"].format(ul), header=
True)
1805 table.adddata(paramhtmldict[
"C22UL"].format(ul), header=
True)
1807 paramhtmldict[
"H0UL"].format(ul) +
" (from C<sub>22</sub>)", header=
True
1809 table.adddata(paramhtmldict[
"ELL"] +
" (from C<sub>22</sub>)", header=
True)
1810 table.adddata(paramhtmldict[
"Q22"] +
" (from C<sub>22</sub>)", header=
True)
1811 table.adddata(
"ratio", header=
True)
1813 if not self._biaixal:
1815 paramhtmldict[
"I21UL"].format(ul), header=
True
1817 table.adddata(paramhtmldict[
"I31UL"].format(ul), header=
True)
1820 "Error... do not know how to output results table for this situation.",
1826 table.adddata(paramhtmldict[
"SNR"], header=
True)
1829 table.adddata(paramhtmldict[
"MAXL"], header=
True)
1832 table.adddata(paramhtmldict[
"BSN"], header=
True)
1835 if len(self.
_ifos_ifos) > 2
and "Joint" in self.
_ifos_ifos:
1836 table.adddata(paramhtmldict[
"BCI"], header=
True)
1837 table.adddata(paramhtmldict[
"BCIN"], header=
True)
1839 for ifo
in self.
_ifos_ifos:
1841 table.adddata(
"{}".format(ifo), dataclass=ifo)
1844 for p
in [
"c21",
"c22"]:
1846 self.
_posteriors_posteriors[ifo][p].samples, upperlimit=(ul / 100.0)
1848 table.adddata(
"{}".format(
exp_str(Cul)), dataclass=ifo)
1850 self.
_C21_C21[ifo] = Cul
1852 self.
_C22_C22[ifo] = Cul
1854 self.
_h0ul_h0ul[ifo] = self.
_C22_C22[ifo] * 2.0
1856 "{}".format(
exp_str(self.
_h0ul_h0ul[ifo])), dataclass=ifo
1865 self.
_posteriors_posteriors[ifo][
"h0"].samples, upperlimit=(ul / 100.0)
1867 self.
_h0ul_h0ul[ifo] = h0ul
1868 table.adddata(
"{}".format(
exp_str(h0ul)), dataclass=ifo)
1873 table.adddata(
"*", dataclass=ifo)
1876 self.
_h0ul_h0ul[ifo], freq, dist
1884 self.
_q22_q22[ifo] =
None
1885 table.adddata(
"*", dataclass=ifo)
1888 table.adddata(
"{}".format(
exp_str(self.
_q22_q22[ifo])), dataclass=ifo)
1893 table.adddata(
"*", dataclass=ifo)
1896 table.adddata(
"%.02f" % self.
_sdratio_sdratio[ifo], dataclass=ifo)
1901 self.
_posteriors_posteriors[ifo][
"I21"].samples, upperlimit=(ul / 100.0)
1903 table.adddata(
"{}".format(
exp_str(self.
_I21_I21[ifo])), dataclass=ifo)
1906 self.
_posteriors_posteriors[ifo][
"I31"].samples, upperlimit=(ul / 100.0)
1908 table.adddata(
"{}".format(
exp_str(self.
_I31_I31[ifo])), dataclass=ifo)
1912 table.adddata(
"%.1f" % self.
_optimal_snrs_optimal_snrs[ifo], dataclass=ifo)
1914 table.adddata(
"*", dataclass=ifo)
1918 "%.f" % (self.
_maxL_maxL[ifo] / np.log(10.0)), dataclass=ifo
1921 "%.1f" % (self.
_Bsn_Bsn[ifo] / np.log(10.0)), dataclass=ifo
1925 if len(self.
_ifos_ifos) > 2
and "Joint" in self.
_ifos_ifos:
1928 "%.1f" % (self.
_Bci_Bci / np.log(10.0)), dataclass=ifo
1931 "%.1f" % (self.
_Bcin_Bcin / np.log(10.0)), dataclass=ifo
1934 table.adddata(
"*", dataclass=ifo)
1935 table.adddata(
"*", dataclass=ifo)
1944 samples = self.
_posteriors_posteriors[ifo][param].samples.squeeze()
1946 lowbound, highbound, _ = self.
_ci_loop_ci_loop(samples, ci)
1949 if paramval !=
None:
1952 for cit
in range(1, 101):
1953 l, h, cr = self.
_ci_loop_ci_loop(samples, cit)
1954 if paramval >= l
and paramval <= h:
1961 return lowbound, highbound, cival
1963 def _ci_loop(self, sortedsamples, ci):
1964 lowbound = sortedsamples[0]
1965 highbound = sortedsamples[-1]
1966 cregion = highbound - lowbound
1967 lsam = len(sortedsamples)
1968 cllen =
int(lsam * float(ci) / 100.0)
1969 for j
in range(lsam - cllen):
1970 if sortedsamples[j + cllen] - sortedsamples[j] < cregion:
1971 lowbound = sortedsamples[j]
1972 highbound = sortedsamples[j + cllen]
1973 cregion = highbound - lowbound
1975 return lowbound, highbound, cregion
1980 Get information (evidence ratios and SNRs) from any the background analyses
1996 self.
_ifos_ifos_ifos = list(backgrounddirs.keys())
2021 self.
_figlimits_figlimits = [(0.0,
None), ()]
2027 "whichtruth":
"all",
2028 "scatter_kwargs": {
"alpha": 0.5},
2044 for i, ifo
in enumerate(self.
_ifos_ifos_ifos):
2045 if ifo
not in Bsn
or ifo
not in snrs:
2047 "Error... Bsn/SNR dictionary is not consistent with the background directories dictionary.",
2062 if os.path.isdir(os.path.join(self.
_backgrounddirs_backgrounddirs[ifo], d))
2064 dirlen.append(len(self.
_dir_lists_dir_lists[ifo]))
2067 "Error... no background results directories were present for '%s'."
2075 if dirlen[i] != dirlen[0]:
2077 "Error... number of background results directories not then same for different detectors."
2108 def _get_snrs(self):
2115 def _get_bayes_factors(self):
2117 incoherent = np.zeros(
2122 for i, pdir
in enumerate(self.
_dir_lists_dir_lists[ifo]):
2123 pfiles = os.listdir(pdir)
2125 for pfile
in pfiles:
2127 pfile,
"posterior_samples*.hdf"
2128 )
or fnmatch.fnmatch(pfile,
"posterior_samples*.h5"):
2130 os.path.join(pdir, pfile)
2140 "Error... no HDF5 file with 'posterior_samples' in the name was found in '%s'."
2158 def _get_bsn_prob(self):
2163 kernel = stats.gaussian_kde(self.
_Bsn_Bsn_Bsn[ifo])
2164 self.
_Bsn_prob_Bsn_prob[ifo] = kernel.integrate_box_1d(
2168 def _get_bci_prob(self):
2169 kernel = stats.gaussian_kde(self.
_Bci_Bci_Bci)
2171 kernel = stats.gaussian_kde(self.
_Bcin_Bcin_Bcin)
2190 "bsn", np.array([self.
_Bsn_Bsn_Bsn[ifo]]).T / np.log(10.0)
2199 truths[ifo] = [self.
_snrs_fore_snrs_fore[ifo], self.
_Bsn_fore_Bsn_fore[ifo] / np.log(10.0)]
2203 bins=
int(np.log2(len(snrs.samples))),
2205 credintervals=credint,
2240 bins=
int(np.log2(len(snrs.samples))),
2242 credintervals=credint,
2252 background_plots_table =
htmltag(
2253 "h2",
"Evidence distributions", newline=
True
2264 os.path.basename(bsnplot[0]),
2265 '<img class="backgroundplot" src="{}"/>'.format(
2266 os.path.basename(bsnplot[0])
2272 bciplot = self.
bci_plotbci_plot(which=
"bci")
2275 os.path.basename(bciplot[0]),
2276 '<img class="backgroundplot" src="{}"/>'.format(
2277 os.path.basename(bciplot[0])
2284 bcinplot = self.
bci_plotbci_plot(which=
"bcin")
2287 os.path.basename(bcinplot[0]),
2288 '<img class="backgroundplot" src="{}"/>'.format(
2289 os.path.basename(bcinplot[0])
2296 innertable =
htmltable(tableclass=
"evidencetable")
2298 innertable.adddata(
" ")
2300 "Probability of background distribution being greater than foreground",
2301 colspan=(len(self.
_ifos_ifos_ifos) + cols - 1),
2305 innertable.adddata(
"Detector", header=
True)
2307 innertable.adddata(ifo, dataclass=ifo)
2309 innertable.adddata(
"B<sub>CvI</sub>")
2311 innertable.adddata(
"B<sub>CvIN</sub>")
2314 innertable.adddata(
" ")
2316 innertable.adddata(
exp_str(self.
bsn_probbsn_prob(ifo)), dataclass=ifo)
2325 table.adddata(innertable.tabletext, colspan=cols)
2327 background_plots_table += table.tabletext
2329 return background_plots_table
2332 if __name__ ==
"__main__":
2333 description =
"""This script will create a results page for a single pulsar from the known pulsar analysis pipeline. A configuration (.ini) file is required."""
2334 epilog =
"""An example configuration file could contain the following:
2336 # a section for general analysis information
2338 parfile = 'path_to_par_file' # the path to the pulsar parameter file
2339 detectors = ['H1', 'L1'] # a list of the detectors to use
2340 with_joint = True # a boolean stating whether to also add the joint multi-detector analysis
2341 joint_only = False # a boolean stating whether to only output the joint multi-detector analysis
2342 with_background = False # a boolean stating whether to include background analyses
2343 injection = False # a boolean stating whether this pulsar is a software/hardware injection
2344 upper_limit = 95 # the percentage credible upper limit value
2345 credible_interval = [95] # a list of the percentage credible intervals for output statistics
2346 use_gw_phase = False # a boolean stating whether to assume the initial phase parameter is the rotational, or gravitational wave (l=m=2), phase (e.g. if looking a hardware injections)
2347 harmonics = [2] # a list of the frequency harmonics used in this analysis
2348 model_type = waveform # either 'waveform' (default) or 'source' specify the parameterisation
2349 biaxial = False # set whether the signal searched for was from a biaxial source
2350 priorfile = 'path_to_prior' # the path to the prior file used in the analysis (if given priors will be plotted)
2352 # a section for parameter estimation files
2353 [parameter_estimation]
2354 posteriors = {'H1': 'path_to_H1_posteriors', 'L1': 'path_to_L1_posteriors', 'Joint': 'path_to_Joint_posteriors'} # a dictionary (keyed on detectors) pointing to the locations of posterior sample files
2355 background = {'H1': 'path_to_H1_background_dir', 'L1': 'path_to_L1_background_dir', 'Joint': 'path_to_Joint_backgroud_dir'} # a dictionary (keyed on detectors) pointing to directories containing the background posterior files
2357 # a section for pre-processed data information
2359 files = {'H1': 'path_to_H1_data', 'L1': 'path_to_L1_data'} # a dictionary (keyed on detectors) pointing to the locations (or lists of locations for multiple harmonics) of pre-processed data files
2361 # a section for the output location for this pulsar
2363 path = 'path_to_output_base_directory' # the path to the base directory in which the results page will be created
2364 indexpage = 'path_to_index_page' # an optional path (relative to the base directory) to the index page containing results from multiple pulsars
2366 # a section for plotting options
2368 all_posteriors = False # a boolean stating whether to show joint posterior plots of all parameters (default: False)
2369 subtract_truths = False # a boolean stating whether to subtract the true/heterodyned value from any phase parameters to centre the plot at zero for that value
2370 show_contours = False # a boolean stating whether to show probabilty contours on 2D posterior plots (default: False)
2371 eps_output = False # a boolean stating whether to also output eps versions of figures (png figures will automatically be produced)
2372 pdf_output = False # a boolean stating whether to also output pdf versions of figures (png figures will automatically be produced)
2376 parser = argparse.ArgumentParser(
2377 description=description,
2379 formatter_class=argparse.RawDescriptionHelpFormatter,
2381 parser.add_argument(
"inifile", help=
"The configuration (.ini) file")
2384 opts = parser.parse_args()
2386 inifile = opts.inifile
2394 "Error... cannot parse configuration file '%s'" % inifile, file=sys.stderr
2400 outdir = cp.get(
"output",
"path")
2403 "Error... no output directory 'path' specified in [output] section.",
2409 if not os.access(outdir, os.W_OK)
and not os.path.isdir(
2416 "Error... cannot make output directory '%s'." % outdir, file=sys.stderr
2422 indexpage = cp.get(
"output",
"indexpage")
2429 parfile = cp.get(
"general",
"parfile")
2432 "Error... Pulsar parameter 'parfile' must specified in the [general] section.",
2442 "Error... Pulsar parameter (.par) file '%s' could not be opened!" % parfile,
2451 "Error... no PSRJ name set in pulsar parameter file '%s'." % parfile,
2459 "Error... no 'F0' value in the parameter file '%s'." % parfile,
2470 upperlim = ast.literval_eval(cp.get(
"general",
"upper_limit"))
2476 credints = ast.literval_eval(cp.get(
"general",
"credible_interval"))
2482 injection = cp.getboolean(
"general",
"injection")
2490 usegwphase = cp.getboolean(
"general",
"use_gw_phase")
2496 priorfile = cp.get(
"general",
"priorfile")
2501 dist = p1_I = assoc = sdlim = f1sd =
None
2506 "http://www.atnf.csiro.au/people/pulsar/psrcat/proc_form.php?version="
2509 atnfurl +=
"&startUserDefined=true&pulsar_names=" + re.sub(
r"\+",
"%2B", pname)
2510 atnfurl +=
"&ephemeris=long&submit_ephemeris=Get+Ephemeris&state=query"
2513 jsonfile = os.path.join(outdir, pname +
".json")
2515 if os.path.isfile(jsonfile):
2517 fp = open(jsonfile,
"r")
2518 info = json.load(fp)
2522 dist = info[
"Pulsar data"][
"DIST"]
2523 p1_I = info[
"Pulsar data"][
"P1_I"]
2524 assoc = info[
"Pulsar data"][
"ASSOC"]
2528 "Warning... could not read in JSON file '%s'." % jsonfile,
2534 if pinfo
is not None:
2535 dist, p1_I, assoc, atnfurlref = pinfo
2539 dist = par[
"DIST"] / KPC
2545 if f1sd
is not None and dist
is not None:
2550 jointonly = cp.getboolean(
"general",
"joint_only")
2556 harmonics = ast.literal_eval(cp.get(
"general",
"harmonics"))
2562 modeltype = cp.get(
"general",
"model_type")
2564 modeltype =
"waveform"
2566 if modeltype
not in [
"waveform",
"source"]:
2568 "Error... unknown 'model type' '%s' specified." % modeltype, file=sys.stderr
2573 biaxial = cp.getboolean(
"general",
"biaxial")
2579 with_background = cp.getboolean(
"general",
"with_background")
2581 with_background =
False
2585 backgrounddir = ast.literal_eval(
2586 cp.get(
"parameter_estimation",
"background")
2589 with_background =
False
2593 allposteriors = cp.getboolean(
"plotting",
"all_posteriors")
2595 allposteriors =
False
2599 subtracttruths = cp.getboolean(
"plotting",
"subtract_truths")
2601 subtracttruths =
False
2605 showcontours = cp.getboolean(
"plotting",
"show_contours")
2607 showcontours =
False
2612 witheps = cp.getboolean(
"plotting",
"eps_output")
2617 figformat.append(
"eps")
2621 withpdf = cp.getboolean(
"plotting",
"pdf_output")
2626 figformat.append(
"pdf")
2635 ifos = ast.literal_eval(cp.get(
"general",
"detectors"))
2638 "Error... could not parse list of 'detectors' in the [general] section.",
2643 if not isinstance(ifos, list):
2645 "Error... the 'detectors' value in the [general] section must be a list.",
2652 "Error... the 'detectors' value in the [general] section must contain at least one detector name.",
2660 withjoint = cp.getboolean(
"general",
"with_joint")
2666 preprocdat = ast.literal_eval(cp.get(
"data",
"files"))
2669 "Error... could not parse dictionary of 'files' in the [data] section.",
2674 if not isinstance(preprocdat, dict):
2676 "Error... the 'files' value in the [data] section must be a dictionary.",
2683 if ifo
not in preprocdat:
2685 "Error... no pre-processed data file is given for '%s'." % ifo,
2692 preprocdat, outdir, figformats=figformat, harmonics=harmonics
2696 if withjoint
or jointonly:
2697 ifos.append(
"Joint")
2701 postfiles = ast.literal_eval(cp.get(
"parameter_estimation",
"posteriors"))
2704 "Error... could not parse dictionary of 'posteriors' in the [parameter_estimation] section.",
2709 if not isinstance(postfiles, dict):
2711 "Error... the 'posteriors' value in the [parameter_estimation] section must be a dictionary.",
2717 if ifo
not in postfiles:
2719 "Error... no posterior file is given for '%s'." % ifo, file=sys.stderr
2723 if not os.path.isfile(postfiles[ifo]):
2725 "Error... posterior file '%s' for '%s' does not exist."
2726 % (postfiles[ifo], ifo),
2732 linktable =
htmltag(
"div", tagstyle=
"text-align: left; float: left")
2739 htmlinput[
"psrname"] = pname
2740 htmlinput[
"title"] = pname
2742 titlename =
"INJ " + pname
2744 titlename =
"PSR " + pname
2746 htmlinput[
"h1title"] =
atag(atnfurl, linktext=titlename).text
2748 htmlinput[
"h1title"] = titlename
2752 htmlinput[
"pulsartable"] = psrtable
2759 harmonics=harmonics,
2760 modeltype=modeltype,
2763 usegwphase=usegwphase,
2764 subtracttruths=subtracttruths,
2765 priorfile=priorfile,
2766 showcontours=showcontours,
2770 htmlinput[
"limitstable"] = postinfo.create_limits_table(
2771 f0, sdlim=sdlim, dist=dist, ul=upperlim
2774 htmlinput[
"selectedposteriors"] = postinfo.create_joint_plots_table(
2775 title=
"Selected parameters"
2779 htmlinput[
"jointposteriors"] = postinfo.create_joint_plots_table(allparams=
True)
2782 +
atag(
"#selectedposteriors", linktext=
"Selected").text
2784 +
atag(
"#jointposteriors", linktext=
"All").text
2786 dataclass=
"rightborder",
2789 htmlinput[
"jointposteriors"] =
""
2791 atag(
"#selectedposteriors", linktext=
"Posteriors").text,
2792 dataclass=
"rightborder",
2806 htmlinput[
"evidenceplots"] = bginfo.create_background_table()
2808 atag(
"#evidenceplots", linktext=
"Backgrounds").text, dataclass=
"rightborder"
2811 htmlinput[
"evidenceplots"] =
""
2814 if datatable
is not None:
2815 htmlinput[
"dataplots"] =
str(datatable)
2817 atag(
"#dataplots", linktext=
"Data Plots").text, dataclass=
"rightborder"
2821 htmlinput[
"posteriorsamples"] = postinfo.create_sample_plot_table(
2822 figformats=figformat
2825 atag(
"#posteriorsamples", linktext=
"Samples").text, dataclass=
"rightborder"
2829 htmlinput[
"posteriorstats"] = postinfo.create_stats_table(credints=credints)
2830 linkstable.adddata(
atag(
"#posteriorstats", linktext=
"Statistics").text)
2832 linktable.set_tagtext(linkstable.tabletext)
2835 if indexpage !=
None:
2837 "div", tagstyle=
"text-align: left; float: right; padding-right: 8px"
2839 indexlink.set_tagtext(
atag(indexpage, linktext=
"Index Page").text)
2840 indexlinktxt = indexlink.text
2844 htmlinput[
"linkstable"] = linktable.text + indexlinktxt
2847 cssfile = os.path.join(outdir,
"resultspage.css")
2848 fp = open(cssfile,
"w")
2849 fp.write(result_page_css)
2852 htmlinput[
"cssfile"] = os.path.basename(cssfile)
2855 now = datetime.datetime.now()
2858 htmlinput[
"footer"] =
"{} - {}<br><br>Command lines used:<br>{}<br>{}<br>".format(
2859 __author__, now.strftime(
"%a %d %b %Y"),
" ".join(sys.argv), __version__
2864 htmlfile = os.path.join(outdir, pname +
".html")
2865 fp = open(htmlfile,
"w")
2866 fp.write(htmlpage.format(**htmlinput))
2869 print(
"Error... there was a problem outputting the html page.", file=sys.stderr)
2878 info[
"Pulsar data"] = {}
2879 info[
"Pulsar data"][
"F0"] = f0
2880 info[
"Pulsar data"][
"F0ROT"] = f0
2881 info[
"Pulsar data"][
"F0GW"] = 2.0 * f0
2882 info[
"Pulsar data"][
"F1"] = f1
2883 info[
"Pulsar data"][
"F1ROT"] = f1
2884 info[
"Pulsar data"][
"F1GW"] = 2.0 * f1
2885 info[
"Pulsar data"][
"F1SD"] = f1sd
2886 info[
"Pulsar data"][
2889 info[
"Pulsar data"][
"DIST"] = dist
2890 info[
"Pulsar data"][
"RA"] = par[
"RA_RAD"]
2891 info[
"Pulsar data"][
"DEC"] = par[
"DEC_RAD"]
2892 info[
"Pulsar data"][
"START"] = par[
"START"]
2893 info[
"Pulsar data"][
"FINISH"] = par[
"FINISH"]
2894 info[
"Pulsar data"][
"BINARY"] = par[
"BINARY"]
2895 info[
"Pulsar data"][
"PEPOCH"] = par[
"PEPOCH"]
2896 info[
"Pulsar data"][
"POSEPOCH"] = par[
"POSEPOCH"]
2897 info[
"Pulsar data"][
"EPHEM"] = par[
"EPHEM"]
2898 info[
"Pulsar data"][
"UNITS"] = par[
"UNITS"]
2899 info[
"Pulsar data"][
"ASSOC"] = assoc
2900 info[
"Pulsar data"][
"spin-down limit"] = sdlim
2901 info[
"Pulsar data"][
"par file"] = parfile
2902 info[
"Pulsar data"][
"ATNF URL"] = atnfurl
2907 info[ifo][
"Upper limits"] = {}
2908 info[ifo][
"Upper limits"][
"credible region"] = upperlim
2909 info[ifo][
"Upper limits"][
"H0"] = postinfo.h0_ul(ifo)
2910 info[ifo][
"Upper limits"][
"ELL"] = postinfo.ellipticity_ul(ifo)
2911 info[ifo][
"Upper limits"][
"Q22"] = postinfo.q22_ul(ifo)
2912 info[ifo][
"Upper limits"][
"C21"] = postinfo.C21_ul(ifo)
2913 info[ifo][
"Upper limits"][
"C22"] = postinfo.C22_ul(ifo)
2914 info[ifo][
"Upper limits"][
"I21"] = postinfo.I21_ul(ifo)
2915 info[ifo][
"Upper limits"][
"I31"] = postinfo.I21_ul(ifo)
2916 info[ifo][
"Upper limits"][
"spin-down ratio"] = postinfo.sdlim_ratio(ifo)
2919 info[ifo][
"Bayes factors"] = {}
2920 info[ifo][
"Bayes factors"][
"Signal vs Noise"] = postinfo.bsn[ifo]
2923 info[ifo][
"Bayes factors"][
"Coherent vs Incoherent"] = postinfo.bci
2924 info[ifo][
"Bayes factors"][
2925 "Coherent vs Incoherent or Noise"
2928 info[ifo][
"SNR"] = postinfo.snr(ifo)
2932 info[ifo][
"Amplitude spectral density"] = {}
2934 if len(harmonics) == 1:
2935 info[ifo][
"Amplitude spectral density"][
"Spectrum"] = datatable.asds[
2938 info[ifo][
"Amplitude spectral density"][
"Mean"] = np.mean(
2939 datatable.asds[harmonics[0]][ifo]
2941 info[ifo][
"Amplitude spectral density"][
"Median"] = np.median(
2942 datatable.asds[harmonics[0]][ifo]
2944 info[ifo][
"Amplitude spectral density"][
"Maximum"] = np.max(
2945 datatable.asds[harmonics[0]][ifo]
2949 info[ifo][
"Amplitude spectral density"][
2950 "%df harmonic" %
int(h)
2952 info[ifo][
"Amplitude spectral density"][
"%df harmonic" %
int(h)][
2954 ] = datatable.asds[h][ifo].tolist()
2955 info[ifo][
"Amplitude spectral density"][
"%df harmonic" %
int(h)][
2957 ] = np.mean(datatable.asds[h][ifo])
2958 info[ifo][
"Amplitude spectral density"][
"%df harmonic" %
int(h)][
2960 ] = np.median(datatable.asds[h][ifo])
2961 info[ifo][
"Amplitude spectral density"][
"%df harmonic" %
int(h)][
2963 ] = np.max(datatable.asds[h][ifo])
2965 jsonfile = os.path.join(outdir, pname +
".json")
2966 fp = open(jsonfile,
"w")
2967 json.dump(info, fp, indent=2)
Class to make and return a html table.
A class to create a html tag.
Get information (evidence ratios and SNRs) from any the background analyses.
def bsn_plot(self, credint=[0.5, 0.95])
def create_background_table(self)
def bci_plot(self, credint=[0.5, 0.95], which="bci")
def __init__(self, backgrounddirs, snrs, Bsn, outputdir, Bci=None, Bcin=None, showcontours=True)
def _get_bayes_factors(self)
def analysis_stats_td(self, ifo)
def __init__(self, datafiles, outputdir, figformats=["png"], asdtime=86400, harmonics=[2.0])
Initialise with a dictionary keyed in detector names containing paths to the equivalent pre-processed...
Get sample posteriors and created a set of functions for outputting tables, plots and posterior stati...
def __init__(self, postfiles, outputdir, ifos=None, harmonics=[2], modeltype="waveform", biaxial=False, usegwphase=False, parfile=None, priorfile=None, subtracttruths=False, showcontours=False)
Initialise with a dictionary keyed in detector names containing paths to the equivalent posterior sam...
def create_joint_plots_table(self, allparams=False, title="Joint distributions")
def create_sample_plot_table(self, figformats=["png"])
def create_stats_table(self, credints=[95])
def _get_bayes_factors(self)
def _ci_loop(self, sortedsamples, ci)
def create_limits_table(self, freq, sdlim=None, dist=None, ul=95)
def plot_prior(self, ax, param, prior, orientation="horizontal", truth=0.0, npoints=100)
def ellipticity_ul(self, ifo)
def create_joint_posterior_plot(self, parameters, bins=20, ifo=None, truths=None, credintervals=[0.9], filename=None, figformats=["png"], ratio=3, figlimits=None, contourlimits=None, jointsamples=True, whichtruth=None, scatter_kwargs={})
def sdlim_ratio(self, ifo)
def get_bayes_factor(self, postfile)
_injection_credible_regions
def credible_interval(self, ifo, param, ci=95, paramval=None)
def exp_str(f, p=1, otype="html")
def pulsar_nest_to_posterior(postfile, nestedsamples=False, removeuntrig=True)
This function will import a posterior sample file created by lalapps_nest2pos (or a nested sample fil...
def upper_limit_greedy(pos, upperlimit=0.95, nbins=100)
def h0_to_quadrupole(h0, freq, dist)
def spin_down_limit(freq, fdot, dist)
def plot_posterior_chain(poslist, param, ifos, grr=None, withhist=0, mplparams=False)
def get_atnf_info(psr)
Get the pulsar (psr) distance (DIST in kpc), proper motion corrected period derivative (P1_I) and any...
def plot_Bks_ASDs(Bkdata, delt=86400, plotpsds=True, plotfscan=False, removeoutlier=None, mplparams=False)
def h0_to_ellipticity(h0, freq, dist)
def create_psr_table(par)
Create a html table of some information from the pulsar parameter file.
def set_spin_down(p1_I, assoc, f0, f1, n=5.0)
Set the spin-down of the source based on the intrinsic period derivative (p1_I) corrected for any pro...