26from igwn_ligolw
import ligolw
27from igwn_ligolw
import lsctables
28from igwn_ligolw
import table
29from igwn_ligolw
import utils
32import matplotlib.pyplot
as pp
37import scipy.stats
as ss
42 ligolw.LIGOLWContentHandler.__init__(self,document)
43 self.
tabname=lsctables.SimBurstTable.tableName
47 if attrs.has_key(
'Name')
and table.Table.TableName(attrs[
'Name'])==self.
tabname:
50 ligolw.LIGOLWContentHandler.startElement(self,name,attrs)
53 ligolw.LIGOLWContentHandler.startElement(self,name,attrs)
55 if self.
intable: ligolw.LIGOLWContentHandler.endElement(self,name)
58posterior_name_to_sim_burst_extractor = {
59 'frequency' :
lambda sb: sb.frequency,
60 'duration' :
lambda sb: sb.duration,
61 'quality' :
lambda sb: sb.q,
62 'hrss' :
lambda sb: sb.hrss,
63 'psi' :
lambda sb: sb.psi,
64 'time' :
lambda sb: sb.time_geocent_gps + 1e-9*sb.time_geocent_gps_ns,
65 'ra' :
lambda sb: sb.ra,
66 'dec' :
lambda sb: sb.dec,
67 'polar_angle':
lambda sb:sb.pol_ellipse_angle,
68 'polar_eccentricity':
lambda sb:sb.pol_ellipse_e,
69 'alpha':
lambda sb:sb.pol_ellipse_angle
73posterior_name_to_latex_name = {
76 'duration' :
r'$\tau$',
82 'polar_angle' :
r'$\xi_a$',
83 'polar_eccentricity' :
r'$\xi_e$',
84 'alpha' :
r'$\zeta_{orb}$',
90 """Returns the fraction of samples, ``xs``, that fall below the value
94 nbelow = np.sum(xs < x)
96 return float(nbelow)/float(xs.shape[0])
98def pp_plot(ps, title=None, outfile=None):
99 """Generates a p-p plot for the given ps.
101 :param ps: The p-values whose cumulative distribution is to be
104 :param title: An (optional) title
for the plot.
106 :param outfile: An (optional) basename
for the plot file; both
107 basename.png
and basename.pdf will be created.
111 ps = np.atleast_1d(ps)
113 ys = np.zeros(ps.shape[0]+2)
114 ys[:-1] = np.linspace(0, 1, ps.shape[0]+1)
116 xs = np.zeros(ps.shape[0]+2)
120 pp.figure(figsize=(6,6), dpi=100)
123 syn_ps = np.random.uniform(size=ps.shape[0])
124 syn_xs = np.zeros(ps.shape[0]+2)
126 syn_xs[1:-1] = np.sort(syn_ps)
127 pp.plot(syn_xs, ys,
'-', color=
'0.9')
129 pp.plot(xs, ys,
'-k')
130 pp.plot(ys, ys,
'--k')
134 if title
is not None:
137 if outfile
is not None:
138 pp.savefig(outfile +
'.png')
139 pp.savefig(outfile +
'.pdf')
142 """Returns the K-S p-value for the test of the given ``ps`` against a
143 uniform distribution on [0,1].
146 stat, p = ss.kstest(ps, lambda x: x)
151 """Returns a named numpy array of the posterior samples in the file
155 with open(f,
'r')
as inp:
156 header = inp.readline().split()
157 dtype = np.dtype([(n, np.float)
for n
in header])
158 data = np.loadtxt(inp, dtype=dtype)
162def output_html(outdir, ks_pvalues, injnum,skypp=False):
163 """Outputs the HTML page summarizing the results.
166 table_row_template = string.Template("""<tr> <td> ${name} </td>
168 <td> <img src="${name}.png" alt=
"${name} p-p plot" width=
"300" height=
"300" /> </td> <td> <a href=
"${name}.png">PNG</a> <a href=
"${name}.pdf">PDF</a> <a href=
"${name}-ps.dat">p-values</a> </td> </tr>
172 html_template = string.Template("""<!DOCTYPE html>
175 <title> LALInference P-P Plots </title>
180 <p>This page was generated with the output of ${injnum} simulations.</p>
185 <th> Parameter </th> <th> K-S p-value </th> <th> p-p Plot </th> <th> Links </th>
199 if os.path.isdir(os.path.join(outdir,
'prior')):
200 links+=
'<li><a href="prior/">Prior Samples used in this test</a>'
201 if os.path.isdir(os.path.join(outdir,
'injections')):
202 links+=
'<li><a href="injections/">Posteriors for each injection</a>'
206 for par, pv
in ks_pvalues.items():
207 tablerows.append(table_row_template.substitute(name=par, pvalue=
str(pv)))
208 tablerows =
'\n'.join(tablerows)
213 skysub=
'<tr> <td> sky </td> <td> See Plot </td> <td> <img src="sky_p-p.png" alt="sky p-p plot" width="300" height="300" /> </td> <td> <a href="sky_p-p.png">PNG</a> <a href="sky_p-p.pdf">PDF</a></td> </tr>'
215 html = html_template.substitute(tablerows=tablerows, injnum=
str(injnum), linkstr=links,skypp=skysub)
217 with open(os.path.join(outdir,
'index.html'),
'w')
as out:
220if __name__ ==
'__main__':
221 USAGE=
'''%prog [options] posfile1.dat posfile2.dat ...
222 Generate PP analysis for a set of injections. posfiles must be
in same order
as injections.
'''
223 parser = optparse.OptionParser(USAGE)
224 parser.add_option('--injXML', action=
'store', type=
'string', dest=
'injxml',
225 help=
'sim_burst XML file for injections')
226 parser.add_option(
'--outdir', action=
'store', type=
'string',
227 help=
'output directory')
229 parser.add_option(
'--postsamples', action=
'store', type=
'string',
230 default=
'posterior_samples.dat',
231 help=
'filename for posterior samples files')
233 parser.add_option(
'--par', action=
'append', default=[], type=
'string',
234 help=
'parameter names for the p-p plot')
235 parser.add_option(
'--skyPPfolder', action=
'store',dest=
'skypp',type=
'string',default=
None,help=
'Path to folder containing png/pdf with 2D skyarea PP plots')
237 (options, args) = parser.parse_args()
239 injs = lsctables.SimBurstTable.get_table(utils.load_filename(options.injxml,contenthandler=LIGOLWContentHandlerExtractSimBurstTable))
241 if options.par == []:
242 parameters = [
'frequency',
'quality',
'hrss',
'ra',
'dec',
'psi',
'time',
'alpha',
'polar_eccentricity']
244 parameters = options.par
247 os.mkdir(options.outdir)
254 for index,posfile
in enumerate(posfiles):
258 true_params = injs[index]
262 print(
"not found %s \n"%posfile)
265 for par
in parameters:
267 samples = psamples[par]
268 true_value = posterior_name_to_sim_burst_extractor[par](true_params)
272 pvalues[par].append(p)
281 for par, ps
in pvalues.items():
282 pp_plot(ps, title=posterior_name_to_latex_name[par], outfile=os.path.join(options.outdir, par))
285 np.savetxt(os.path.join(options.outdir, par +
'-ps.dat'), np.reshape(ps, (-1, 1)))
288 if options.skypp
is not None:
290 if os.path.isdir(options.skypp):
291 for i
in [
'png',
'pdf']:
292 if os.path.isfile(os.path.join(options.skypp,
'p-p.%s'%i)):
293 inf=os.path.join(os.path.realpath(options.skypp),
'p-p.%s'%i)
294 outf=os.path.join(options.outdir,
'sky_p-p.%s'%i)
295 os.system(
'cp %s %s'%(inf,outf))
298 print(
"could not find %s\n"%os.path.join(options.skypp,
'p-p.%s'%i))
300 print(
"skyPPfolder %s doesn't seem to be a valid folder or cannot be read. Skipping skyPP plot\n"%os.path.realpath(options.skypp))
def __init__(self, document)
def startElement(self, name, attrs)
def endElement(self, name)
def fractional_rank(x, xs)
Returns the fraction of samples, xs, that fall below the value x.
def output_html(outdir, ks_pvalues, injnum, skypp=False)
Outputs the HTML page summarizing the results.
def pp_kstest_pvalue(ps)
Returns the K-S p-value for the test of the given ps against a uniform distribution on [0,...
def pp_plot(ps, title=None, outfile=None)
Generates a p-p plot for the given ps.
def read_posterior_samples(f)
Returns a named numpy array of the posterior samples in the file f.