LALInference 4.1.10.1-bf6a62b
cbcBayesCompPos.py
Go to the documentation of this file.
1##python
2# -*- coding: utf-8 -*-
3#
4# cbcBayesCompPos.py Copyright 2010--2012 Benjamin Aylott
5# <benjamin.aylott@ligo.org>, Will M. Farr <will.farr@ligo.org>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20# MA 02110-1301, USA.
21
22#standard library imports
23import os
24import sys
25from time import strftime
26import copy
27import getpass
28
29#related third party imports
30import numpy as np
31from numpy import floor
32
33import scipy.stats as ss
34
35import matplotlib as mpl
36mpl.use("AGG")
37from matplotlib import pyplot as plt
38from matplotlib import colors as mpl_colors
39from matplotlib import cm as mpl_cm
40from matplotlib.ticker import ScalarFormatter
41
42#local application/library specific imports
43import lalinference.bayespputils as bppu
44from lalinference import git_version
45
46__author__="Ben Aylott <benjamin.aylott@ligo.org>, Will M. Farr <will.farr@ligo.org>"
47__version__= "git id %s"%git_version.id
48__date__= git_version.date
49
50#List of parameters to plot/bin . Need to match (converted) column names.
51oneDMenu=['mtotal','m1','m2','mchirp','mc','chirpmass','distance','distMPC','dist','iota','psi','eta','q','asym_massratio','spin1','spin2','a1','a2','phi1','theta1','phi2','theta2','costilt1','costilt2','costhetas','cosbeta','phi_orb', 'lambdat', 'dlambdat', 'lambda1', 'lambda2', 'lam_tilde', 'dlam_tilde','theta_jn','a1z','a2z'] + bppu.spininducedquadParams + bppu.snrParams + bppu.spinParams + bppu.cosmoParam + bppu.calParams + bppu.tigerParams + bppu.lorentzInvarianceViolationParams + bppu.qnmtestParams
52#List of parameter pairs to bin . Need to match (converted) column names.
53twoDGreedyMenu=[['mc','eta'],['mchirp','eta'],['chirpmass','eta'],['mc','q'],['mchirp','q'],['chirpmass','q'],['mc','asym_massratio'],['mchirp','asym_massratio'],['chirpmass','asym_massratio'],['m1','m2'],['mtotal','eta'],['distance','iota'],['dist','iota'],['dist','m1'],['ra','dec'],['dist','cos(iota)'],['phi_orb','iota'],['theta_jn','dist'],['spin1','spin2'],['spin1','mchirp'],['spin1','m1'],['a1','a2'],['a1','mchirp'],['a1','m1'],['tilt1','tilt2'],['tilt1','mchirp'],['tilt1','m1'],['a1z','a2z']]
54#Bin size/resolution for binning. Need to match (converted) column names.
55
56#Convert parameter names to LaTeX; if not mentioned here, just use parameter name.
57paramNameLatexMap = {'m1': 'm_1', 'm2' : 'm_2', 'mtotal' : r'M_{\rm tot}', 'mchirp' : r'\mathcal{M}',
58 'mc': r'\mathcal{M}', 'distance' : 'd', 'distMPC' : 'd', 'dist': 'd',
59 'iota': r'\iota', 'psi': r'\psi', 'eta': r'\eta', 'asym_massratio': 'q', 'a1': 'a_1',
60 'a2': 'a_2', 'phi1': r'\phi_1', 'phi2': r'\phi_2', 'theta1': r'\theta_1', 'theta2': r'\theta_2',
61 'cos(tilt1)': r'\cos t_1', 'cos(tilt2)': r'\cos t_2', 'cos(thetas)': r'\cos \theta_s',
62 'cosbeta': r'\cos \beta', 'phi_orb': r'\phi_{\rm orb}', 'cos(beta)': r'\cos \beta',
63 'cos(iota)': r'\cos \iota', 'tilt1': r't_1', 'tilt2': r't_2', 'ra': r'\alpha', 'dec': r'\delta',
64 'lambdat' : r'\tilde{\Lambda}', 'dlambdat': r'\delta \tilde{\Lambda}',
65 'lambda1' : r'\lambda_1', 'lambda2': r'\lambda_2',
66 'lam_tilde' : r'\tilde{\Lambda}', 'dlam_tilde': r'\delta \tilde{\Lambda}','dchiMinus2':r'$d\chi_{-2}$','dchiMinus1':r'$d\chi_{-1}$','dchi0':r'\delta\chi_0','dchi1':r'\delta\chi_1','dchi2':r'\delta\chi_2','dchi3':r'\delta\chi_3','dchi3S':r'\delta\chi_{3S}','dchi3NS':r'\delta\chi_{3NS}','dchi4':r'\delta\chi_4','dchi4S':r'\delta\chi_{4S}','dchi4NS':r'\delta\chi_{4NS}','dchi5':r'\delta\chi_5','dchi5S':r'\delta\chi_{5S}','dchi5NS':r'\delta\chi_{5NS}','dchi5l':r'\delta\chi_{5l}','dchi5lS':r'\delta\chi_{5lS}','dchi5lNS':r'\delta\chi_{5lNS}','dchi6':r'\delta\chi_6','dchi6S':r'\delta\chi_{6S}','dchi6NS':r'\delta\chi_{6NS}','dchi6l':r'\delta\chi_{6l}','dchi7':r'\delta\chi_7','dchi7S':r'\delta\chi_{7S}','dchi7NS':r'\delta\chi_{7NS}','dbeta2':r'\delta\beta_2','dbeta3':r'\delta\beta_3','dsigma2':r'\delta\sigma_2','dsigma3':r'\delta\sigma_3','dsigma4':r'\delta\sigma_4','dbeta2':r'\delta\beta_2','dbeta3':r'\delta\beta_3' ,'log10lambda_a':r'$\log\lambda_{\mathbb{A}}$','log10lambda_eff':r'$\log\lambda_{eff}$','log10livamp':r'$\log \mathbb{A}$','lambda_a':r'$\lambda_{\mathbb{A}}$','lambda_eff':r'$\lambda_{eff}$','liv_amp':r'$\mathbb{A}$','dquadmons':r'\delta\kappa_s','dchikappaS':r'\delta\chi_{kappa_{S}}','dchikappaA':r'\delta\chi_{\kappa_{A}}','damp21':r'$\delta A_{21}$', 'damp33':r'$\delta A_{33}$',
67'domega220': r'$d\omega_{220}$', 'dtau220': r'$d\tau_{220}$',
68 'domega210': r'$d\omega_{210}$', 'dtau210': r'$d\tau_{210}$',
69 'domega330': r'$d\omega_{330}$','dtau330': r'$d\tau_{330}$',
70 'domega440': r'$d\omega_{440}$', 'dtau440': r'$d\tau_{440}$',
71 'domega550': r'$d\omega_{550}$', 'dtau550': r'$d\tau_{550}$',
72 'dc1':r'$\delta c_1$', 'dc2':r'$\delta c_2$', 'dc4':r'$\delta c_4$', 'dcl':r'$\delta c_l$', 'db1':r'$\delta b_1$', 'db2':r'$\delta b_2$', 'db3':r'$\delta b_3$', 'db4':r'$\delta b_4$'
73}
74
75# Only these parameters, in this order appear in confidence level table.
76clTableParams = ['mchirp', 'mc', 'chirpmass', 'eta', 'q', 'm1', 'm2', 'distance', 'distMPC', 'dist', 'cos(iota)', 'iota', 'theta_jn', 'psi', 'ra', 'dec', 'time', 'phase', 'a1', 'a2', 'costilt1', 'costilt2','dchiMinus2','dchiMinus1','dchi0','dchi1','dchi2','dchi3','dchi3S','dchi3NS','dchi4','dchi4S','dchi4NS','dchi5','dchi5S','dchi5NS','dchi5l','dchi5lS','dchi5lNS','dchi6','dchi6S','dchi6NS','dchi6l','dchi7','dchi7S','dchi7NS','dbeta2','dbeta3','dsigma2','dsigma3','dsigma4','dbeta2','dbeta3', 'log10lambda_eff','log10lambda_a','log10livamp','lambda_eff','lambda_a','liv_amp','dquadmons','dchikappaS','dchikappaA','domega220', 'dtau220', 'domega210', 'dtau210', 'domega330', 'dtau330', 'domega440', 'dtau440', 'domega550', 'dtau550', 'db1', 'db2', 'db3', 'db4', 'dc1', 'dc2', 'dc4', 'dcl','damp21', 'damp33']
77
78
79greedyBinSizes={'mc':0.001,'m1':0.1,'m2':0.1,'mass1':0.1,'mass2':0.1,'mtotal':0.1,'eta':0.001,'q':0.001,'asym_massratio':0.001,'iota':0.05,'time':1e-4,'distance':5.0,'dist':1.0,'mchirp':0.01,'chirpmass':0.01,'a1':0.02,'a2':0.02,'phi1':0.05,'phi2':0.05,'theta1':0.05,'theta2':0.05,'ra':0.05,'dec':0.005,'psi':0.1,'cos(iota)':0.01, 'cos(tilt1)':0.01, 'cos(tilt2)':0.01, 'tilt1':0.05, 'tilt2':0.05, 'cos(thetas)':0.01, 'cos(beta)':0.01,'phi_orb':0.2,'inclination':0.05,'theta_jn':0.05,'spin1':0.02,'spin2':0.02}
80for s in bppu.snrParams:
81 greedyBinSizes[s]=0.02
82for s in bppu.calParams:
83 greedyBinSizes[s]=0.02
84for s in bppu.tigerParams + bppu.lorentzInvarianceViolationParams + bppu.qnmtestParams:
85 greedyBinSizes[s]=0.01
86for s in bppu.spinParams:
87 greedyBinSizes[s]=0.02
88for s in bppu.cosmoParam:
89 greedyBinSizes[s]=0.1
90greedyBinSizes['redshift']=0.005
91
92#Confidence levels
93OneDconfidenceLevels=[0.9]#[0.68,0.9,0.95,0.997]
94TwoDconfidenceLevels=OneDconfidenceLevels
95
96#2D plots list
97#twoDplots=[['mc','eta'],['mchirp','eta'],['m1','m2'],['mtotal','eta'],['distance','iota'],['dist','iota'],['RA','dec'],['ra','dec'],['m1','dist'],['m2','dist'],['psi','iota'],['psi','distance'],['psi','dist'],['psi','phi0'],['dist','cos(iota)']]
98twoDplots=[['m1','m2'],['mass1','mass2'],['RA','dec'],['ra','dec'],['cos(thetas)','cos(beta)'],['distance','iota'],['dist','iota'],['dist','cosiota'],['distance','cosiota'],['psi','iota'],['psi','distance'],['psi','phi0'],['dist','cos(iota)'],['phi_orb','iota'],['distance','inclination'],['dist','inclination'],['theta_jn','dist'],['spin1','spin2'],['spin1','mchirp'],['spin1','m1'],['a1','a2'],['a1','mchirp'],['a1','m1'],['tilt1','tilt2'],['tilt1','mchirp'],['tilt1','m1']]
99allowed_params=['mtotal','m1','m2','mchirp','mc','chirpmass','q','asym_massratio','distance','distMPC','dist','iota','psi','eta','ra','dec','a1','a2','spin1','spin2','phi1','theta1','phi2','theta2','cos(iota)','cos(tilt1)','cos(tilt2)','tilt1','tilt2','cos(thetas)','cos(beta)','phi_orb','inclination', 'logl', 'lambdat', 'dlambdat', 'lambda1', 'lambda2', 'lam_tilde', 'dlam_tilde','theta_jn','a1z','a2z','dquadmons','dquadmona','dquadmon1','dquadmon2']+bppu.snrParams + bppu.spinParams + bppu.cosmoParam + bppu.calParams + bppu.tigerParams
100
101def open_url(url,username,password):
102
103 import urllib
104 import urllib2
105 import urlparse
106
107 parsed_url=urlparse.urlparse(url)
108 url=urlparse.urljoin(parsed_url.geturl(),'posterior_samples.dat')
109
110
111 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
112 urllib2.install_opener(opener)
113
114 body={'username':username,'password':password}
115 txdata = urllib.urlencode(body) # if we were making a POST type request, we could encode a dictionary of values here - using urllib.urlencode
116 txheaders = {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} # fake a user agent, some websites (like google) don't like automated exploration
117
118 req = urllib2.Request(parsed_url[0]+'://'+parsed_url[1], txdata, txheaders)
119
120 resp = opener.open(req) # save a cookie
121 dump=resp.read()
122 resp.close()
123 try:
124 req = urllib2.Request(url, txdata, txheaders) # create a request object
125 handle = opener.open(req) # and open it to return a handle on the url
126 data = handle.read()
127 f = file('posterior_samples.dat', 'w')
128 f.write(data)
129 f.close()
130
131 except IOError as e:
132 print('We failed to open "%s".' % url)
133 if hasattr(e, 'code'):
134 print('We failed with error code - %s.' % e.code)
135 elif hasattr(e, 'reason'):
136 print("The error object has the following 'reason' attribute :", e.reason)
137 print("This usually means the server doesn't exist, is down, or we don't have an internet connection.")
138 sys.exit()
139 else:
140 print('Here are the headers of the page :')
141 print(handle.info()) # handle.read() returns the page, handle.geturl() returns the true url of the page fetched (in case urlopen has followed any redirects, which it sometimes does)
142
143 return HTMLSource
144
146 while L:
147 i = L.pop()
148 for j in L: yield i, j
149
150def open_url_curl(url,args=[]):
151 import subprocess
152
153 kerberos_args = "--insecure -c /tmp/{0}_cookies -b /tmp/{0}_cookies --negotiate --user : --location-trusted".format(getpass.getuser()).split()
154
155 retcode=subprocess.call(['curl'] + kerberos_args + [url] + args)
156
157 return retcode
158
159def test_and_switch_param(common_output_table_header,test,switch):
160 try:
161 idx=common_output_table_header.index(test)
162 common_output_table_header[idx]=switch
163 print("Re-labelled %s -> %s"%(test,switch))
164 except:
165 pass
166
167 return
168
169def compare_plots_one_param_pdf(list_of_pos_by_name,param,analyticPDF=None):
170 """
171 Plots a gaussian kernel density estimate for a set
172 of Posteriors onto the same axis.
173
174 @param list_of_pos_by_name: a dictionary of {name:Posterior} class instances.
175
176 @param param: parameter name to compare
177
178 @param analyticPDF: Optional function to over-plot
179
180 """
181
182 #Create common figure
183 myfig=plt.figure(figsize=(6,4.5),dpi=150)
184
185 list_of_pos=list(list_of_pos_by_name.values())
186 list_of_pos_names=list(list_of_pos_by_name.keys())
187
188 allmins=map(lambda a: np.min(a[param].samples), list_of_pos)
189 allmaxes=map(lambda a: np.max(a[param].samples), list_of_pos)
190 min_pos=np.min(allmins)
191 max_pos=np.max(allmaxes)
192 print('Found global min: %f, max: %f'%(min_pos,max_pos))
193
194 gkdes={}
195 injvals=[]
196 for name,posterior in list_of_pos_by_name.items():
197
198 pos_samps=posterior[param].samples
199 if posterior[param].injval is not None:
200 injvals.append(posterior[param].injval)
201
202 min_pos_temp=np.min(pos_samps)
203 max_pos_temp=np.max(pos_samps)
204
205 if min_pos_temp<min_pos:
206 min_pos=min_pos_temp
207 if max_pos_temp>max_pos:
208 max_pos=max_pos_temp
209
210 injpar=posterior[param].injval
211
212 gkdes[name]=posterior[param].gaussian_kde
213
214 if gkdes:
215 ind=np.linspace(min_pos,max_pos,101)
216
217 kdepdfs=[]
218 for name,gkde in gkdes.items():
219 kdepdf=gkde.evaluate(ind)
220 kdepdfs.append(kdepdf)
221 plt.plot(ind,np.transpose(kdepdf),label=name)
222 plt.grid()
223 plt.legend()
224 plt.xlabel(bppu.plot_label(param))
225 plt.xlim(min_pos,max_pos)
226 plt.ylabel('Probability Density')
227 try:
228 plt.tight_layout()
229 except:
230 pass
231 if injvals:
232 print("Injection parameter is %f"%(float(injvals[0])))
233 injpar=injvals[0]
234 if min(pos_samps)<injpar and max(pos_samps)>injpar:
235 plt.plot([injpar,injpar],[0,max(kdepdf)],'r-.',scalex=False,scaley=False)
236 if analyticPDF is not None:
237 plt.plot(ind,map(analyticPDF,ind),'r')
238 #
239 return myfig#,rkde
240#
241def compare_plots_one_param_line_hist(list_of_pos_by_name,param,cl,color_by_name,cl_lines_flag=True,legend='right',analyticPDF=None):
242
243
244 """
245 Plots a gaussian kernel density estimate for a set
246 of Posteriors onto the same axis.
247
248 @param list_of_pos_by_name: a dict of Posterior class instances indexed by name
249
250 @param param: parameter name to plot
251
252 @param cl: list of credible levels to plot
253
254 @param color_by_name: dict of colours indexed by name
255
256 @param cl_lines_flag: option to plot credible level lines
257
258 @param legend: matplotlib position for legend
259
260 @param analyticPDF: Optional analytic function to over-plot
261
262 """
263
264 #Create common figure
265 myfig=plt.figure(figsize=(6,4.5),dpi=150)
266 #myfig.add_axes([0.1,0.1,0.65,0.85])
267 #myfig.add_axes([0.15,0.15,0.6,0.76])
268 axes=plt.Axes(myfig,[0.15,0.15,0.6,0.76])
269 myfig.add_axes(axes)
270 majorFormatterX=ScalarFormatter(useMathText=True)
271 majorFormatterX.format_data=lambda data:'%.6g'%(data)
272 majorFormatterY=ScalarFormatter(useMathText=True)
273 majorFormatterY.format_data=lambda data:'%.6g'%(data)
274 majorFormatterX.set_scientific(True)
275 majorFormatterY.set_scientific(True)
276
277 list_of_pos=list(list_of_pos_by_name.values())
278 list_of_pos_names=list(list_of_pos_by_name.keys())
279
280 allmins=map(lambda a: np.min(a[param].samples), list_of_pos)
281 allmaxes=map(lambda a: np.max(a[param].samples), list_of_pos)
282 min_pos=np.min(allmins)
283 max_pos=np.max(allmaxes)
284
285 injvals=[]
286
287 patch_list=[]
288 max_y=0
289
290 posbins=np.linspace(min_pos,max_pos,50)
291
292 for name,posterior in list_of_pos_by_name.items():
293 colour=color_by_name[name]
294 #myfig.gca(autoscale_on=True)
295 if posterior[param].injval:
296 injvals.append(posterior[param].injval)
297
298 try:
299 n,bins=np.histogram(posterior[param].samples,bins=posbins,density=True,new=True)
300 except:
301 n,bins=np.histogram(posterior[param].samples,bins=posbins,density=True)
302 if min(bins)==max(bins):
303 print('Skipping '+param)
304 continue
305 locmaxy=max(n)
306 if locmaxy>max_y: max_y=locmaxy
307#(n, bins, patches)=plt.hist(posterior[param].samples,bins=bins,facecolor='white',label=name,normed=True,hold=True,color=color_by_name[name])#range=(min_pos,max_pos)
308 (n, bins, patches)=plt.hist(posterior[param].samples,bins=bins,histtype='step',label=name,density=True,hold=True,color=color_by_name[name])
309 patch_list.append(patches[0])
310
311 Nchars=max(map(lambda d:len(majorFormatterX.format_data(d)),axes.get_xticks()))
312 if Nchars>8:
313 Nticks=3
314 elif Nchars>5:
315 Nticks=4
316 elif Nchars>4:
317 Nticks=6
318 else:
319 Nticks=6
320 locatorX=mpl.ticker.MaxNLocator(nbins=Nticks)
321 locatorX.view_limits(bins[0],bins[-1])
322 axes.xaxis.set_major_locator(locatorX)
323
324 plt.xlim(min_pos,max_pos)
325 top_cl_intervals_list={}
326 pos_names=list(list_of_pos_by_name.keys())
327
328
329 for name,posterior in list_of_pos_by_name.items():
330 #toppoints,injectionconfidence,reses,injection_area,cl_intervals=bppu.greedy_bin_one_param(posterior,{param:greedyBinSizes[param]},[cl])
331 cl_intervals=posterior[param].prob_interval([cl])
332 colour=color_by_name[name]
333 if cl_intervals[0] is not None and cl_lines_flag:
334 try:
335 plt.plot([cl_intervals[0][0],cl_intervals[0][0]],[0,max_y],color=colour,linestyle='--')
336 plt.plot([cl_intervals[0][1],cl_intervals[0][1]],[0,max_y],color=colour,linestyle='--')
337 except:
338 print("MAX_Y",max_y,[cl_intervals[0][0],cl_intervals[0][0]],[cl_intervals[0][1],cl_intervals[0][1]])
339 top_cl_intervals_list[name]=(cl_intervals[0][0],cl_intervals[0][1])
340
341 if cl_lines_flag:
342 pos_names.append(str(int(cl*100))+'%')
343 patch_list.append(mpl.lines.Line2D(np.array([0.,1.]),np.array([0.,1.]),linestyle='--',color='black'))
344
345 plt.grid()
346 plt.xlim(min_pos,max_pos)
347 if legend is not None:
348 oned_legend=plt.figlegend(patch_list,pos_names,'right')
349 for text in oned_legend.get_texts():
350 text.set_fontsize('small')
351 plt.xlabel(bppu.plot_label(param))
352 plt.ylabel('Probability density')
353 plt.draw()
354 #plt.tight_layout()
355 if injvals:
356 print("Injection parameter is %f"%(float(injvals[0])))
357 injpar=injvals[0]
358 #if min(pos_samps)<injpar and max(pos_samps)>injpar:
359 plt.plot([injpar,injpar],[0,max_y],'r-.',scalex=False,scaley=False,linewidth=4,label='Injection')
360
361 #
362 if analyticPDF is not None:
363 plt.plot(posbins,map(analyticPDF,posbins),'r')
364 return myfig,top_cl_intervals_list#,rkde
365
366#
367def compute_ks_pvalue_matrix(list_of_pos_by_name, param):
368 """Returns a matrix of ks p-value tests between pairs of
369 posteriors on the 1D marginalized distributions for param."""
370
371 poss=list_of_pos_by_name.values()
372
373 N=len(poss)
374
375 matrix=np.zeros((N,N))
376 matrix[:,:]=float('nan')
377
378 for i in range(N):
379 pi=poss[i]
380 for j in range(i+1, N):
381 pj=poss[j]
382
383 d,pvalue=ss.ks_2samp(pi[param].samples.flatten(), pj[param].samples.flatten())
384
385 matrix[i,j]=pvalue
386 matrix[j,i]=pvalue
387
388 return matrix
389
390def compare_plots_one_param_line_hist_cum(list_of_pos_by_name,param,cl,color_by_name,cl_lines_flag=True,analyticCDF=None,legend='auto'):
391
392 """
393 Plots a gaussian kernel density estimate for a set
394 of Posteriors onto the same axis.
395
396 @param list_of_pos_by_name: a dict of Posterior class instances indexed by name
397
398 @param param: name of parameter to plot
399
400 @param cl: list of confidence levels to show
401
402 @param color_by_name: dict of colours indexed by name
403
404 @param cl_lines_flag: Show confidence level lines
405
406 @param analyticCDF: Analytic CDF function to over-plot
407
408 @param legend: legend position to pass to matplotlib
410 """
411
412 #Create common figure
413 myfig=plt.figure(figsize=(6,4.5),dpi=150)
414 myfig.add_axes([0.15,0.15,0.6,0.76])
415 list_of_pos=list(list_of_pos_by_name.values())
416 list_of_pos_names=list(list_of_pos_by_name.keys())
417
418 injvals=[]
419 allmins=map(lambda a: np.min(a[param].samples), list_of_pos)
420 allmaxes=map(lambda a: np.max(a[param].samples), list_of_pos)
421 min_pos=np.min(allmins)
422 max_pos=np.max(allmaxes)
423
424 patch_list=[]
425 max_y=1.
426
427 posbins=np.linspace(min_pos,max_pos,50)
428
429 for name,posterior in list_of_pos_by_name.items():
430 colour=color_by_name[name]
431 #myfig.gca(autoscale_on=True)
432 if posterior[param].injval:
433 injvals.append(posterior[param].injval)
434
435 try:
436 n,bins=np.histogram(posterior[param].samples,bins=posbins,density=True,new=True)
437 except:
438 n,bins=np.histogram(posterior[param].samples,bins=posbins,density=True)
439
440 if min(bins)==max(bins):
441 print('Skipping '+param)
442 continue
443
444 (n, bins, patches)=plt.hist(posterior[param].samples,bins=bins,histtype='step',label=name,density=True,hold=True,color=color_by_name[name],cumulative='True')#range=(min_pos,max_pos)
445
446 patch_list.append(patches[0])
447
448 top_cl_intervals_list={}
449 pos_names=list(list_of_pos_by_name.keys())
450
451
452 for name,posterior in list_of_pos_by_name.items():
453 #toppoints,injectionconfidence,reses,injection_area,cl_intervals=bppu.greedy_bin_one_param(posterior,{param:greedyBinSizes[param]},[cl])
454 cl_intervals=posterior[param].prob_interval([cl])
455 colour=color_by_name[name]
456 if cl_intervals[0] is not None and cl_lines_flag:
457 try:
458 plt.plot([cl_intervals[0][0],cl_intervals[0][0]],[0,max_y],color=colour,linestyle='--')
459 plt.plot([cl_intervals[0][1],cl_intervals[0][1]],[0,max_y],color=colour,linestyle='--')
460 except:
461 print("MAX_Y",max_y,[cl_intervals[0][0],cl_intervals[0][0]],[cl_intervals[0][1],cl_intervals[0][1]])
462 top_cl_intervals_list[name]=(cl_intervals[0][0],cl_intervals[0][1])
463
464 if cl_lines_flag:
465 pos_names.append(str(int(cl*100))+'%')
466 patch_list.append(mpl.lines.Line2D(np.array([0.,1.]),np.array([0.,1.]),linestyle='--',color='black'))
467
468 plt.grid()
469 plt.xlim(min_pos,max_pos)
470 plt.ylim(0,1)
471 if legend:
472 oned_legend=plt.figlegend(patch_list,pos_names,'right')
473 for text in oned_legend.get_texts():
474 text.set_fontsize('small')
475 plt.xlabel(bppu.plot_label(param))
476 plt.ylabel('Cumulative Probability')
477 plt.draw()
478 #plt.tight_layout()
479 if injvals:
480 print("Injection parameter is %f"%(float(injvals[0])))
481 injpar=injvals[0]
482 #if min(pos_samps)<injpar and max(pos_samps)>injpar:
483 plt.plot([injpar,injpar],[0,max_y],'r-.',scalex=False,scaley=False,linewidth=4,label='Injection')
484 if analyticCDF is not None:
485 plt.plot(posbins,map(analyticCDF,posbins),'r')
486 return myfig,top_cl_intervals_list#,rkde
487
488
489def compare_bayes(outdir,names_and_pos_folders,injection_path,eventnum,username,password,reload_flag,clf,ldg_flag,contour_figsize=(4.5,4.5),contour_dpi=250,contour_figposition=[0.15,0.15,0.5,0.75],fail_on_file_err=True,covarianceMatrices=None,meanVectors=None,Npixels2D=50):
490
491 injection=None
492
493 if injection_path is not None and os.path.exists(injection_path) and eventnum is not None:
494 eventnum=int(eventnum)
495 from igwn_ligolw import ligolw, lsctables, utils
496 injections = lsctables.SimInspiralTable.get_table(
497 utils.load_filename(injection_path))
498 if eventnum is not None:
499 if(len(injections)<eventnum):
500 print("Error: You asked for event %d, but %s contains only %d injections" %(eventnum,injection_path,len(injections)))
501 sys.exit(1)
502 else:
503 injection=injections[eventnum]
504
505 #Create analytic likelihood functions if covariance matrices and mean vectors were given
506 analyticLikelihood = None
507 if covarianceMatrices and meanVectors:
508 analyticLikelihood = bppu.AnalyticLikelihood(covarianceMatrices, meanVectors)
509 peparser=bppu.PEOutputParser('common')
510 pos_list={}
511 tp_list={}
512 common_params=None
513 working_folder=os.getcwd()
514 for name,pos_folder in names_and_pos_folders:
515 import urlparse
516
517 pos_folder_url=urlparse.urlparse(pos_folder)
518 pfu_scheme,pfu_netloc,pfu_path,pfu_params,pfu_query,pfu_fragment=pos_folder_url
519
520 if 'http' in pfu_scheme:
521
522 """
523 Retrieve a file over http(s).
524 """
525 downloads_folder=os.path.join(os.getcwd(),"downloads")
526 pos_folder_parse=urlparse.urlparse(pos_folder)
527 pfp_scheme,pfp_netloc,pfp_path,pfp_params,pfp_query,pfp_fragment=pos_folder_parse
528 head,tail=os.path.split(pfp_path)
529 if tail is 'posplots.html' or tail:
530 pos_file_part=head
531 else:
532 pos_file_part=pfp_path
533 pos_file_url=urlparse.urlunsplit((pfp_scheme,pfp_netloc,os.path.join(pos_file_part,'posterior_samples.dat'),'',''))
534 print(pos_file_url)
535 pos_file=os.path.join(os.getcwd(),downloads_folder,"%s.dat"%name)
536
537 if not os.path.exists(pos_file):
538 reload_flag=True
539
540 if reload_flag:
541 if os.path.exists(pos_file):
542 os.remove(pos_file)
543 if not os.path.exists(downloads_folder):
544 os.makedirs(downloads_folder)
545 open_url_curl(pos_file_url,args=["-o","%s"%pos_file])
546
547 elif pfu_scheme is '' or pfu_scheme is 'file':
548 pos_file=os.path.join(pos_folder,'%s.dat'%name)
549 # Try looking for posterior_samples.dat if name.dat doesn't exist
550 if not os.path.exists(pos_file):
551 print('%s does not exist, trying posterior_samples.dat'%(pos_file))
552 pos_file=os.path.join(pos_folder,'posterior_samples.dat')
553 else:
554 print("Unknown scheme for input data url: %s\nFull URL: %s"%(pfu_scheme,str(pos_folder_url)))
555 exit(0)
556
557 print("Reading posterior samples from %s ..."%pos_file)
558
559 try:
560 common_output_table_header,common_output_table_raw=peparser.parse(open(pos_file,'r'))
561 except:
562 print('Unable to read file '+pos_file)
563 continue
564
565 test_and_switch_param(common_output_table_header,'distance','dist')
566 test_and_switch_param(common_output_table_header,'chirpmass','mchirp')
567 test_and_switch_param(common_output_table_header,'mc','mchirp')
568 test_and_switch_param(common_output_table_header,'asym_massratio','q')
569 test_and_switch_param(common_output_table_header,'massratio', 'eta')
570 test_and_switch_param(common_output_table_header,'RA','ra')
571 test_and_switch_param(common_output_table_header,'rightascension','ra')
572 test_and_switch_param(common_output_table_header,'declination','dec')
573 test_and_switch_param(common_output_table_header,'tilt_spin1','tilt1')
574 test_and_switch_param(common_output_table_header,'tilt_spin2','tilt2')
575
576 if 'LI_MCMC' in name or 'FU_MCMC' in name:
577
578 try:
579
580 idx=common_output_table_header.index('iota')
581 print("Inverting iota!")
582
583 common_output_table_raw[:,idx]= np.pi*np.ones(len(common_output_table_raw[:,0])) - common_output_table_raw[:,idx]
584
585 except:
586 pass
587
588
589 # try:
590 # print "Converting phi_orb-> 2phi_orb"
591 # idx=common_output_table_header.index('phi_orb')
592 # common_output_table_header[idx]='2phi_orb'
593 # common_output_table_raw[:,idx]= 2*common_output_table_raw[:,idx]
594 # except:
595 # pass
596
597 try:
598 print("Converting iota-> cos(iota)")
599 idx=common_output_table_header.index('iota')
600 common_output_table_header[idx]='cos(iota)'
601 common_output_table_raw[:,idx]=np.cos(common_output_table_raw[:,idx])
602 except:
603 pass
604
605 #try:
606 # print "Converting tilt1 -> cos(tilt1)"
607 # idx=common_output_table_header.index('tilt1')
608 # common_output_table_header[idx]='cos(tilt1)'
609 # common_output_table_raw[:,idx]=np.cos(common_output_table_raw[:,idx])
610 #except:
611 # pass
612
613 #try:
614 # print "Converting tilt2 -> cos(tilt2)"
615 # idx=common_output_table_header.index('tilt2')
616 # common_output_table_header[idx]='cos(tilt2)'
617 # common_output_table_raw[:,idx]=np.cos(common_output_table_raw[:,idx])
618 #except:
619 # pass
620
621 try:
622 print("Converting thetas -> cos(thetas)")
623 idx=common_output_table_header.index('thetas')
624 common_output_table_header[idx]='cos(thetas)'
625 common_output_table_raw[:,idx]=np.cos(common_output_table_raw[:,idx])
626 except:
627 pass
628
629 try:
630 print("Converting beta -> cos(beta)")
631 idx=common_output_table_header.index('beta')
632 common_output_table_header[idx]='cos(beta)'
633 common_output_table_raw[:,idx]=np.cos(common_output_table_raw[:,idx])
634 except:
635 pass
636
637 try:
638 idx=common_output_table_header.index('f_ref')
639 injFrefs=np.unique(common_output_table_raw[:,idx])
640 if len(injFrefs) == 1:
641 injFref = injFrefs[0]
642 print("Using f_ref in results as injected value")
643 except:
644 injFref = None
645 pass
646
647 pos_temp=bppu.Posterior((common_output_table_header,common_output_table_raw),SimInspiralTableEntry=injection, injFref=injFref)
648
649 if 'a1' in pos_temp.names and min(pos_temp['a1'].samples)[0] < 0:
650 pos_temp.append_mapping('spin1', lambda a:a, 'a1')
651 pos_temp.pop('a1')
652 pos_temp.append_mapping('a1', lambda a:np.abs(a), 'spin1')
653 if 'a2' in pos_temp.names and min(pos_temp['a2'].samples)[0] < 0:
654 pos_temp.append_mapping('spin2', lambda a:a, 'a2')
655 pos_temp.pop('a2')
656 pos_temp.append_mapping('a2', lambda a:np.abs(a), 'spin2')
657
658
659 if 'm1' in pos_temp.names and 'm2' in pos_temp.names:
660 print("Calculating total mass")
661 pos_temp.append_mapping('mtotal', lambda m1,m2: m1+m2, ['m1','m2'])
662 if 'mass1' in pos_temp.names and 'mass2' in pos_temp.names:
663 print("Calculating total mass")
664 pos_temp.append_mapping('mtotal', lambda m1,m2: m1+m2, ['mass1','mass2'])
665
666 try:
667 idx=common_output_table_header.index('m1')
668
669 idx2=common_output_table_header.index('m2')
670
671 if pos_temp['m1'].mean<pos_temp['m2'].mean:
672 print("SWAPPING MASS PARAMS!")
673 common_output_table_header[idx]='x'
674 common_output_table_header[idx2]='m1'
675 common_output_table_header[idx]='m2'
676 pos_temp=bppu.Posterior((common_output_table_header,common_output_table_raw),SimInspiralTableEntry=injection)
677 except:
678 pass
679
680 pos_list[name]=pos_temp
681
682 if common_params is None:
683 common_params=pos_temp.names
684 else:
685 set_of_pars = set(pos_temp.names)
686 common_params=list(set_of_pars.intersection(common_params))
687
688 print("Common parameters are %s"%str(common_params))
689
690 if injection is None and injection_path is not None:
691 injections = SimInspiralUtils.ReadSimInspiralFromFiles([injection_path])
692 injection=bppu.get_inj_by_time(injections,pos_temp.means['time'])
693 if injection is not None:
694 for pos in pos_list.values():
695 pos.set_injection(injection)
696
697 set_of_pars = set(allowed_params)
698 common_params=list(set_of_pars.intersection(common_params))
699
700 print("Using parameters %s"%str(common_params))
701
702 if not os.path.exists(os.path.join(os.getcwd(),'results')):
703 os.makedirs('results')
704
705 if not os.path.exists(outdir):
706 os.makedirs(outdir)
707
708 pdfdir=os.path.join(outdir,'pdfs')
709 if not os.path.exists(pdfdir):
710 os.makedirs(pdfdir)
711
712 greedy2savepaths=[]
713
714 if common_params is not [] and common_params is not None: #If there are common parameters....
715 colorlst=bppu.__default_color_lst
716
717 if len(common_params)>1: #If there is more than one parameter...
718 temp=copy.copy(common_params)
719 #Plot two param contour plots
720
721 #Assign some colours to each different analysis result
722 color_by_name={}
723 hatches_by_name={}
724 my_cm=mpl_cm.Dark2
725 cmap_size=my_cm.N
726 color_idx=0
727 color_idx_max=len(names_and_pos_folders)
728 cmap_array=my_cm(np.array(range(cmap_size)))
729 #cmap_array=['r','g','b','c','m','k','0.5','#ffff00']
730 hatches=['/','\\','|','-','+','x','o','O','.','*']
731 ldg='auto'
732 if not ldg_flag:
733 ldg=None
734 for name,infolder in names_and_pos_folders:
735 #color_by_name=cmap_array[color_idx]
736 color_by_name[name]=cmap_array[int(floor(color_idx*cmap_size/color_idx_max)),:]
737 color_idx=(color_idx+1) % color_idx_max
738 hatches_by_name[name]=hatches[color_idx]
739
740 for i,j in all_pairs(temp):#Iterate over all unique pairs in the set of common parameters
741 pplst=[i,j]
742 rpplst=pplst[:]
743 rpplst.reverse()
744
745 pplst_cond=(pplst in twoDplots)
746 rpplst_cond=(rpplst in twoDplots)
747 if pplst_cond or rpplst_cond:#If this pair of parameters is in the plotting list...
748
749 try:
750 print('2d plots: building ',i,j)
751 greedy2Params={i:greedyBinSizes[i],j:greedyBinSizes[j]}
752 except KeyError:
753 continue
754
755 name_list=[]
756 cs_list=[]
757
758 slinestyles=['solid', 'dashed', 'dashdot', 'dotted']
759
760 fig=bppu.plot_two_param_kde_greedy_levels(pos_list,greedy2Params,TwoDconfidenceLevels,color_by_name,figsize=contour_figsize,dpi=contour_dpi,figposition=contour_figposition,legend=ldg,line_styles=slinestyles,hatches_by_name=hatches_by_name,Npixels=Npixels2D)
761 if fig is None: continue
762 #fig=bppu.plot_two_param_greedy_bins_contour(pos_list,greedy2Params,TwoDconfidenceLevels,color_by_name,figsize=contour_figsize,dpi=contour_dpi,figposition=contour_figposition)
763 greedy2savepaths.append('%s-%s.png'%(pplst[0],pplst[1]))
764 fig.savefig(os.path.join(outdir,'%s-%s.png'%(pplst[0],pplst[1])),bbox_inches='tight')
765 fig.savefig(os.path.join(pdfdir,'%s-%s.pdf'%(pplst[0],pplst[1])),bbox_inches='tight')
766
767
768 plt.clf()
769 oned_data={}
770 #confidence_levels={}
771 confidence_levels=[{},{},{},{}]
772 confidence_uncertainty={}
773 for param in common_params:
774 print("Plotting comparison for '%s'"%param)
775
776 cl_table_header='<table><th>Run</th>'
777 cl_table={}
778 save_paths=[]
779 cl_table_min_max_str='<tr><td> Min | Max </td>'
780 level_index=0
781 for confidence_level in OneDconfidenceLevels:
782 if analyticLikelihood:
783 pdf=analyticLikelihood.pdf(param)
784 cdf=analyticLikelihood.cdf(param)
785 else:
786 pdf=None
787 cdf=None
788 cl_table_header+='<th colspan="2">%i%% (Lower|Upper)</th>'%(int(100*confidence_level))
789 hist_fig,cl_intervals=compare_plots_one_param_line_hist(pos_list,param,confidence_level,color_by_name,cl_lines_flag=clf,legend=ldg,analyticPDF=pdf)
790 hist_fig2,cl_intervals=compare_plots_one_param_line_hist_cum(pos_list,param,confidence_level,color_by_name,cl_lines_flag=clf,analyticCDF=cdf,legend=ldg)
791
792 # Save confidence levels and uncertainty
793 #confidence_levels[param]=[]
794 confidence_levels[level_index][param]=[]
795
796 for name,pos in pos_list.items():
797 median=pos[param].median
798 low,high=cl_intervals[name]
799 #confidence_levels[param].append((name,low,median,high))
800 confidence_levels[level_index][param].append((name,low,median,high))
801
802 level_index=level_index+1
803 cl_bounds=[]
804 poses=[]
805 for name,pos in pos_list.items():
806 cl_bounds.append(cl_intervals[name])
807 poses.append(pos[param])
808 confidence_uncertainty[param]=bppu.confidence_interval_uncertainty(confidence_level, cl_bounds, poses)
809
810 save_path=''
811 if hist_fig is not None:
812 save_path=os.path.join(outdir,'%s_%i.png'%(param,int(100*confidence_level)))
813 save_path_pdf=os.path.join(pdfdir,'%s_%i.pdf'%(param,int(100*confidence_level)))
814 try:
815 plt.tight_layout(hist_fig)
816 plt.tight_layout(hist_fig2)
817 except:
818 pass
819 hist_fig.savefig(save_path,bbox_inches='tight')
820 hist_fig.savefig(save_path_pdf,bbox_inches='tight')
821 save_paths.append(save_path)
822 save_path=os.path.join(outdir,'%s_%i_cum.png'%(param,int(100*confidence_level)))
823 save_path_pdf=os.path.join(pdfdir,'%s_%i_cum.pdf'%(param,int(100*confidence_level)))
824 hist_fig2.savefig(save_path,bbox_inches='tight')
825 hist_fig2.savefig(save_path_pdf,bbox_inches='tight')
826 save_paths.append(save_path)
827 min_low,max_high=cl_intervals.values()[0]
828 for name,interval in cl_intervals.items():
829 low,high=interval
830 if low<min_low:
831 min_low=low
832 if high>max_high:
833 max_high=high
834 try:
835 cl_table[name]+='<td>%s</td><td>%s</td>'%(low,high)
836 except:
837 cl_table[name]='<td>%s</td><td>%s</td>'%(low,high)
838 cl_table_min_max_str+='<td>%s</td><td>%s</td>'%(min_low,max_high)
839 cl_table_str=cl_table_header
840 for name,row_contents in cl_table.items():
841 cl_table_str+='<tr><td>%s<font color="%s"></font></td>'%(name,str(mpl_colors.rgb2hex(color_by_name[name][0:3])))#,'&#183;'.encode('utf-8'))
842
843 cl_table_str+=row_contents+'</tr>'
844 cl_table_str+=cl_table_min_max_str+'</tr>'
845 cl_table_str+='</table>'
846
847 cl_uncer_str='<table> <th>Confidence Relative Uncertainty</th> <th>Confidence Fractional Uncertainty</th> <th>Confidence Percentile Uncertainty</th>\n'
848 cl_uncer_str+='<tr> <td> %g </td> <td> %g </td> <td> %g </td> </tr> </table>'%(confidence_uncertainty[param][0], confidence_uncertainty[param][1], confidence_uncertainty[param][2])
849
850 ks_matrix=compute_ks_pvalue_matrix(pos_list, param)
851
852 N=ks_matrix.shape[0]+1
853
854 # Make up KS-test table
855 ks_table_str='<table><th colspan="%d"> K-S test p-value matrix </th>'%N
856
857 # Column headers
858 ks_table_str+='<tr> <td> -- </td> '
859 for name,pos in pos_list.items():
860 ks_table_str+='<td> %s </td>'%name
861 ks_table_str+='</tr>'
862
863 # Now plot rows of matrix
864 for i in range(len(pos_list)):
865 ks_table_str+='<tr> <td> %s </td>'%(pos_list.keys()[i])
866 for j in range(len(pos_list)):
867 if i == j:
868 ks_table_str+='<td> -- </td>'
869 elif ks_matrix[i,j] < 0.05:
870 # Failing at suspiciously low p-value
871 ks_table_str+='<td> <b> %g </b> </td>'%ks_matrix[i,j]
872 else:
873 ks_table_str+='<td> %g </td>'%ks_matrix[i,j]
874
875 ks_table_str+='</tr>'
876
877 ks_table_str+='</table>'
878
879 oned_data[param]=(save_paths,cl_table_str,ks_table_str,cl_uncer_str)
880
881 # Watch out---using private variable _logL
882 max_logls = [[name,max(pos._logL)] for name,pos in pos_list.items()]
883 dics = [pos.DIC for name, pos in pos_list.items()]
884
885 return greedy2savepaths,oned_data,confidence_uncertainty,confidence_levels,max_logls,dics
886
887def output_confidence_levels_tex(clevels,outpath):
888 """Outputs a LaTeX table of parameter and run medians and confidence levels."""
889 outfile=open(os.path.join(outpath,'confidence_table.tex'), 'w')
890 for level_index in range(len(OneDconfidenceLevels)):
891 params=list(clevels[level_index].keys())
892
893 clevels_by_name={}
894 for param in clTableParams:
895 if param in params:
896 for name,low,med,high in clevels[level_index][param]:
897 if name in clevels_by_name:
898 clevels_by_name[name].append((param,low,med,high))
899 else:
900 clevels_by_name[name] = [(param,low,med,high)]
901
902 try:
903 outfile.write('confidence level %1.3g\n'%OneDconfidenceLevels[level_index])
904 outfile.write(r'\begin{tabular}{|l||')
905 for param in clTableParams:
906 if param in params:
907 outfile.write('c|')
908 outfile.write('}\n')
909
910 outfile.write(r'\hline ')
911 for param in clTableParams:
912 if param in params:
913 tparam=paramNameLatexMap.get(param,param)
914 outfile.write(r'& $%s$ '%tparam)
915 outfile.write('\\\\ \n \\hline \\hline ')
916
917 for name,levels in clevels_by_name.items():
918 outfile.write(name)
919 for param,low,med,high in levels:
920 outfile.write(r' & $%0.5g^{%0.5g}_{%0.5g}$ '%(med,high,low))
921 outfile.write('\\\\ \n')
922
923 outfile.write('\\hline \n \\end{tabular}')
924 finally:
925 outfile.write('\n\n')
926
927 outfile.close()
928
929def output_confidence_levels_dat(clevels,outpath):
930 """Outputs a LaTeX table of parameter and run medians and confidence levels."""
931 outfile=open(os.path.join(outpath,'confidence_table.dat'), 'w')
932 for level_index in range(len(OneDconfidenceLevels)):
933 params=list(clevels[level_index].keys())
934
935 clevels_by_name={}
936 for param in clTableParams:
937 if param in params:
938 for name,low,med,high in clevels[level_index][param]:
939 if name in clevels_by_name:
940 clevels_by_name[name].append((param,low,med,high))
941 else:
942 clevels_by_name[name] = [(param,low,med,high)]
943
944 try:
945 outfile.write('%1.3g\t'%OneDconfidenceLevels[level_index])
946 for param in clTableParams:
947 if param in params:
948 tparam=paramNameLatexMap.get(param,param)
949 outfile.write('%s\t'%param)
950 outfile.write('\n')
951
952 for name,levels in clevels_by_name.items():
953 outfile.write(name)
954 for param,low,med,high in levels:
955 outfile.write('\t%6.6g - %6.6g'%(low,high))
956 outfile.write('\n')
957 finally:
958 outfile.write('\n')
959
960 outfile.close()
961
962def output_confidence_uncertainty(cluncertainty, outpath):
963 outfile=open(os.path.join(outpath, 'confidence_uncertainty.dat'), 'w')
964 try:
965 params=list(cluncertainty.keys())
966 uncer=list(cluncertainty.values())
967
968 outfile.write('# Uncertainty in confidence levels.\n')
969 outfile.write('# First row is relative uncertainty (wrt to parameter mean).\n')
970 outfile.write('# Second row is fractional uncertainty (wrt to combined conf interval).\n')
971 outfile.write('# Third row is percentile uncertainty (wrt combined samples).\n')
972 outfile.write('# ')
973 for param in params:
974 outfile.write(str(param) + ' ')
975 outfile.write('\n')
976
977 rel = np.array([d[0] for d in uncer])
978 fracs = np.array([d[1] for d in uncer])
979 quants = np.array([d[2] for d in uncer])
980
981 np.savetxt(outfile, np.reshape(rel, (1, -1)))
982 np.savetxt(outfile, np.reshape(fracs, (1, -1)))
983 np.savetxt(outfile, np.reshape(quants, (1,-1)))
984 finally:
985 outfile.close()
986
987if __name__ == '__main__':
988 from optparse import OptionParser
989 parser=OptionParser()
990 parser.add_option("-o","--outpath", dest="outpath",help="Make page and plots in DIR.", metavar="DIR")
991 parser.add_option("-p","--pos",dest="pos_list",action="append",help="Path to folders containing output of cbcBayesPostProc.")
992 parser.add_option("-n","--name",dest="names",action="append",help="Name of posterior result e.g. followupMCMC 2.5PN (optional)")
993 parser.add_option("-i","--inj",dest="inj",help="Path of injection XML containing SimInspiralTable (optional).")
994 parser.add_option("-e","--eventnum",dest="eventnum",help="Sim ID of injection described in injection XML (optional).")
995 parser.add_option("-u",dest="username",help="User name for https authenticated content (optional).")
996 parser.add_option("-x",dest="password",help="Password for https authenticated content (optional).")
997 parser.add_option("--reload",dest="reload_flag",action="store_true",help="Re-download all pos files (optional).")
998 parser.add_option("--hide-cl-lines",dest="clf",action="store_false",default=True,help="Hide confidence level lines on 1D plots for clarity (optional).")
999 parser.add_option("--contour-dpi",dest="cdpi",default=250,help="DPI for contour plot (optional).")
1000 parser.add_option("--contour-width",dest="cw",default=7,help="Width (in inches) of contour plots (optional).")
1001 parser.add_option("--contour-height",dest="ch",default=6,help="Height (in inches) of contour plots (optional).")
1002 parser.add_option("--contour-plot-width",dest="cpw",default=0.5,help="Relative width of plot element 0.15<width<1 (optional).")
1003 parser.add_option("--contour-plot-height",dest="cph",default=0.76,help="Relative height of plot element 0.15<width<1 (optional).")
1004 parser.add_option("--no-legend",dest="ldg_flag",action="store_false",default=True,help="Hide legend (optional).")
1005 parser.add_option("--ignore-missing-files",dest="readFileErr",default=False,action="store_true",help="Do not fail when files are missing (optional).")
1006 parser.add_option("-c","--covarianceMatrix",dest="covarianceMatrices",action="append",default=None,help="CSV file containing covariance (must give accompanying mean vector CSV. Can add more than one matrix.")
1007 parser.add_option("-m","--meanVectors",dest="meanVectors",action="append",default=None,help="Comma separated list of locations of the multivariate gaussian described by the correlation matrix. First line must be list of params in the order used for the covariance matrix. Provide one list per covariance matrix.")
1008 parser.add_option("--no2D",dest="no2d",action="store_true",default=False,help="Disable 2D plots")
1009 parser.add_option("--npixels-2d",dest="npixels_2d",action="store",type="int",default=50,help="Number of pixels on a side of the 2D plots (default 50)",metavar="N")
1010
1011 (opts,args)=parser.parse_args()
1012
1013 if opts.outpath is None:
1014 print("No output directory specified. Output will be saved to PWD : %s"%os.getcwd())
1015 outpath=os.getcwd()
1016 else:
1017 outpath=opts.outpath
1018
1019 if opts.pos_list is None:
1020 print("No input paths given!")
1021 exit(1)
1022
1023 if opts.names is None:
1024 print("No names given, making some up!")
1025 names=[]
1026 for i in range(len(opts.pos_list)):
1027 names.append(str(i))
1028 else:
1029 names=opts.names
1030
1031 if len(opts.pos_list)!=len(names):
1032 print("Either add names for all posteriors or dont put any at all!")
1033
1034 # Sort inputs alphabetically
1035 names,pos_list = zip(*sorted(zip(names,opts.pos_list)))
1036
1037 if opts.no2d:
1038 twoDplots=[]
1039
1040
1041 greedy2savepaths,oned_data,confidence_uncertainty,confidence_levels,max_logls,dics=compare_bayes(outpath,zip(names,pos_list),opts.inj,opts.eventnum,opts.username,opts.password,opts.reload_flag,opts.clf,opts.ldg_flag,contour_figsize=(float(opts.cw),float(opts.ch)),contour_dpi=int(opts.cdpi),contour_figposition=[0.15,0.15,float(opts.cpw),float(opts.cph)],fail_on_file_err=not opts.readFileErr,covarianceMatrices=opts.covarianceMatrices,meanVectors=opts.meanVectors,Npixels2D=int(opts.npixels_2d))
1042
1043 ####Print Confidence Levels######
1044 output_confidence_levels_tex(confidence_levels,outpath)
1045 output_confidence_levels_dat(confidence_levels,outpath)
1046
1047 ####Save confidence uncertainty#####
1048 output_confidence_uncertainty(confidence_uncertainty,outpath)
1049
1050 ####Print HTML!#######
1051
1052 compare_page=bppu.htmlPage('Compare PDFs (single event)',css=bppu.__default_css_string)
1053
1054 param_section=compare_page.add_section('Meta')
1055
1056 param_section_write='<div><p>This comparison was created from the following analyses</p>'
1057 param_section_write+='<table border="1">'
1058 param_section_write+='<th>Analysis</th> <th> max(log(L)) </th> <th> DIC </th>'
1059 for (name,logl_max), dic in zip(max_logls, dics):
1060 param_section_write+='<tr><td><a href="%s">%s</a></td> <td>%g</td> <td>%.1f</td></tr>'%(dict(zip(names,pos_list))[name],name,logl_max,dic)
1061 param_section_write+='</table></div>'
1062
1063 param_section.write(param_section_write)
1064 param_section.write('<div><p><a href="confidence_table.tex">LaTeX table</a> of medians and confidence levels.</p></div>')
1065 if oned_data:
1066
1067 param_section=compare_page.add_section('1D marginal posteriors')
1068
1069 for param_name,data in oned_data.items():
1070 param_section.h3(param_name)
1071 save_paths,cl_table_str,ks_table_str,cl_uncer_str=data
1072 clf_toggle=False
1073 for save_path in save_paths:
1074 head,plotfile=os.path.split(save_path)
1075 param_section.write('<img src="%s"/>'%str(plotfile))
1076
1077 param_section.write(cl_table_str)
1078 param_section.write(cl_uncer_str)
1079 param_section.write(ks_table_str)
1080
1081 if greedy2savepaths:
1082
1083 param_section=compare_page.add_section('2D greedy bin histograms')
1084 for plot_path in greedy2savepaths:
1085 temp,param_name=os.path.split(plot_path)
1086 param_name=param_name.split('.')[0]
1087 head,plotfile=os.path.split(plot_path)
1088 param_section.write('<img src="%s"/>'%str(plotfile))#str(os.path.relpath(plot_path,outpath)))
1089
1090
1091
1092 compare_page_footer=compare_page.add_section('')
1093 compare_page_footer.p('Produced using cbcBayesCompPos.py at '+strftime("%Y-%m-%d %H:%M:%S")+' .')
1094
1095 cc_args=copy.deepcopy(sys.argv)
1096
1097 #remove username and password
1098 try:
1099 user_idx=cc_args.index('-u')
1100 cc_args[user_idx+1]='<LIGO username>'
1101 except:
1102 pass
1103
1104 try:
1105 pass_idx=cc_args.index('-x')
1106 cc_args[pass_idx+1]='<LIGO password>'
1107 except:
1108 pass
1109
1110 cc_args_str=''
1111 for cc_arg in cc_args:
1112 cc_args_str+=cc_arg+' '
1113
1114 compare_page_footer.p('Command line: %s'%cc_args_str)
1115 compare_page_footer.p(git_version.verbose_msg)
1116
1117
1118 resultspage=open(os.path.join(outpath,'index.html'),'w')
1119 resultspage.write(str(compare_page))
1120 resultspage.close()
#define max(a, b)
def open_url_curl(url, args=[])
def compute_ks_pvalue_matrix(list_of_pos_by_name, param)
Returns a matrix of ks p-value tests between pairs of posteriors on the 1D marginalized distributions...
def compare_bayes(outdir, names_and_pos_folders, injection_path, eventnum, username, password, reload_flag, clf, ldg_flag, contour_figsize=(4.5, 4.5), contour_dpi=250, contour_figposition=[0.15, 0.15, 0.5, 0.75], fail_on_file_err=True, covarianceMatrices=None, meanVectors=None, Npixels2D=50)
def compare_plots_one_param_pdf(list_of_pos_by_name, param, analyticPDF=None)
Plots a gaussian kernel density estimate for a set of Posteriors onto the same axis.
def output_confidence_uncertainty(cluncertainty, outpath)
def output_confidence_levels_dat(clevels, outpath)
Outputs a LaTeX table of parameter and run medians and confidence levels.
def output_confidence_levels_tex(clevels, outpath)
Outputs a LaTeX table of parameter and run medians and confidence levels.
def open_url(url, username, password)
def compare_plots_one_param_line_hist_cum(list_of_pos_by_name, param, cl, color_by_name, cl_lines_flag=True, analyticCDF=None, legend='auto')
Plots a gaussian kernel density estimate for a set of Posteriors onto the same axis.
def compare_plots_one_param_line_hist(list_of_pos_by_name, param, cl, color_by_name, cl_lines_flag=True, legend='right', analyticPDF=None)
Plots a gaussian kernel density estimate for a set of Posteriors onto the same axis.
def test_and_switch_param(common_output_table_header, test, switch)