Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInference 4.1.9.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
lalinference_coherence_test.py
Go to the documentation of this file.
1##python
2'''
3This program simply computes the bayes factor between the coherent and incoherent models
4given as input the B files for the run.
5'''
6
7from __future__ import print_function
8
9from optparse import OptionParser
10import sys
11import os
12import matplotlib
13matplotlib.use("Agg")
14from pylab import loadtxt
15from math import log,exp
16
17usage='''%prog [options] coherent_B.txt incoherent1_B.txt incoherent2_B.txt ... incoherentN_B.txt
18%prog takes a list of arguments which specify FIRST the coherent B.txt file, followed by all the
19B.txt files from the individual runs on each IFO. The coherent file must be specified first.
20
21The code will then perform either the test of coherent vs incoherent signal models, i.e.
22B_{CI} = Z_co / Z_1 * Z_2 * Z_3
23
24or a test of coherent vs incoherent
25B_{CIN} = Z_co / (Z_1 * Z_2 * Z_3 + N_{123})
26
27or the test of coherent vs ( incoherent signal or noise ) models, i.e.
28B_{CIN} = Z_co / Z_{inc OR noise}
29with Z_{inc OR noise} = sum over all permutations of the signal and noise hypotheses in each detector
30e.g. for 2 detectors:
31Z_{inc OR noise} =
32see also https://dcc.ligo.org/LIGO-T1600068
33
34Output will be written to stdout, and to a text file specified by the --outfile option.
35
36'''
37
38parser=OptionParser(usage)
39parser.add_option("-c","--coherent-incoherent",action="store_true",dest="ci",help="Perform coherence test of Coherent signal vs incoherent signal",default=False )
40parser.add_option("-n","--coherent-incoherent-noise", dest="cin", action="store_true", help="Perform coherence test of coherent signal vs incoherent signal or noise", default=False )
41parser.add_option("-b","--new-coherent-incoherent-noise", dest="cin_or_n", action="store_true", help="Perform coherence test of coherent signal vs incoherent signal or noise using the most inclusive hypothesis", default=False )
42parser.add_option("-o","--outfile",default=None, help="Optional output file name", metavar="OUTFILE.txt",type="string",action="store")
43
44(opts,args)=parser.parse_args()
45
46def get_metadata_hdf5(filename,key):
47 import h5py
48 with h5py.File(filename,'r') as hdf:
49 g=hdf['lalinference']
50 if(len(g.keys()))>1:
51 print('Error: multiple runs %s found in input file %s'%g.keys(),filename)
52 sys.exit(1)
53 # Descend into run group
54 g=g[list(g.keys())[0]]
55 return g.attrs[key]
56
57# Sanity check input arguments
58if len(args)==0:
59 print('No input files specified')
60 sys.exit(1)
61
62if( sum([opts.ci,opts.cin,opts.cin_or_n])!=1):
63 print('Please specify one of -c, -n or -b. See help for details.')
64 sys.exit(1)
65
66cofile=args[0]
67incofiles=args[1:]
68
69if len(incofiles)<2:
70 print('Cannot perform coherence test on less than 2 IFOs')
71 sys.exit(0)
72
73if len(incofiles)==0:
74 print('Error: You must specify incoherent input files')
75 sys.exit(1)
76
77def logadd(a,b):
78 if(a>b): (a,b)=(b,a)
79 return (b+log(1+exp(a-b)))
80
81def get_metadata_old(Bfile,key):
82 print('Looking for '+Bfile)
83 if os.access(Bfile,os.R_OK):
84 outstat = loadtxt(Bfile)
85 if key=='log_evidence':
86 return outstat[1]
87 if key=='log_noise_evidence':
88 return outstat[2]
89 if key=='log_bayes_factor':
90 return outstat[0]
91 print('Unknown key %s'%(key))
92 return None
93 else:
94 return None
95
96def get_metadata(filename,key):
97 if '.h5' in filename or '.hdf' in filename:
98 return get_metadata_hdf5(filename,key)
99 else:
100 return get_metadata_old(filename,key)
101
102Zco = get_metadata(cofile,'log_evidence')
103Zinco=0
104Z_single_noise = [ get_metadata(inco,'log_noise_evidence') for inco in incofiles]
105Z_single_signal = [ get_metadata(inco,'log_evidence') for inco in incofiles]
106
107# we compute now the evidence for the hypothesis "incoherent signal OR noise" as the
108# sum over all posible permutations over mutually exclusive sub propositions
109
110from itertools import combinations
111try:
112 from scipy.special import logsumexp
113except ImportError: # scipy < 0.19.0
114 from scipy.misc import logsumexp
115
116def not_seen(t, seen=set()):
117 return False if t[0] in seen or t[1] in seen else seen.update(t) or True
118
119Z_incoherentORnoise = logsumexp([sum(p) for p in list(filter(lambda t, seen=set(): False if t[0] in seen or t[1] in seen else seen.update(t) or True, combinations(Z_single_signal+Z_single_noise, len(Z_single_signal))))])
120
121for inco in incofiles:
122 Zinco+=get_metadata(inco,'log_evidence')
123Znoise = get_metadata(cofile,'log_noise_evidence')
124
125if(opts.outfile is not None):
126 out=open(opts.outfile,'w')
127
128if(opts.ci):
129 B=Zco-Zinco
130if (opts.cin):
131 B=Zco-logadd(Zinco,Znoise)
132if(opts.cin_or_n):
133 B=Zco-Z_incoherentORnoise
134
135print('%.3f'%(B))
136
137if(opts.outfile is not None ):
138 print('%.3f'%(B), file=out)
139 out.close()