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