24 from pylal
import spawaveform
29 from scipy
import integrate
30 from scipy
import interpolate
35 from glue.ligolw
import ligolw, lsctables, array, param, utils, types
36 from gstlal.pipeio
import repack_complex_array_to_real, repack_real_array_to_complex
42 def Theta(eta, Mtot, t):
44 theta = eta / (5.0 * Mtot * Tsun) * -t
47 def freq(eta, Mtot, t):
48 theta = Theta(eta, Mtot, t)
50 f = 1.0 / (8.0 * Tsun * scipy.pi * Mtot) * (
52 (743.0/2688.0 + 11.0 /32.0 * eta) * theta**(-5.0 /8.0) -
53 3.0 * scipy.pi / 10.0 * theta**(-3.0 / 4.0) +
54 (1855099.0 / 14450688.0 + 56975.0 / 258048.0 * eta + 371.0 / 2048.0 * eta**2.0) * theta**(-7.0/8.0))
57 def Phase(eta, Mtot, t, phic = 0.0):
58 theta = Theta(eta, Mtot, t)
59 phi = phic - 2.0 / eta * (
61 (3715.0 /8064.0 +55.0 /96.0 *eta) * theta**(3.0/8.0) -
62 3.0 *scipy.pi / 4.0 * theta**(1.0/4.0) +
63 (9275495.0 / 14450688.0 + 284875.0 / 258048.0 * eta + 1855.0 /2048.0 * eta**2) * theta**(1.0/8.0))
66 def Amp(eta, Mtot, t):
67 theta = Theta(eta, Mtot, t)
71 f = 1.0 / (8.0 * Tsun * scipy.pi * Mtot) * (theta**(-3.0/8.0))
72 amp = - 4.0/Mpc * Tsun * c * (eta * Mtot ) * (Tsun * scipy.pi * Mtot * f)**(2.0/3.0);
75 def waveform(m1, m2, fLow, fhigh, sampleRate):
76 deltaT = 1.0 / sampleRate
77 T = spawaveform.chirptime(m1, m2 , 4, fLow, fhigh)
78 tc = -spawaveform.chirptime(m1, m2 , 4, fhigh)
82 n_start = math.floor((tc-T) / deltaT + 0.5)
83 n_end = min(math.floor(tc/deltaT), -1)
84 t = numpy.arange(n_start, n_end+1, 1) * deltaT
86 eta = m1 * m2 / Mtot**2
87 f = freq(eta, Mtot, t)
88 amp = Amp(eta, Mtot, t);
89 phase = Phase(eta, Mtot, t);
92 def sigmasq2(mchirp, fLow, fhigh, psd_interp):
98 const = numpy.sqrt((5.0 * math.pi)/(24.*c**3))*(G*mchirp*M)**(5./6.)*math.pi**(-7./6.)/Mpc
99 return const * numpy.sqrt(4.*integrate.quad(
lambda x: x**(-7./3.) / psd_interp(x), fLow, fhigh)[0])
107 def get_iir_sample_rate(xmldoc):
110 def sample_rates_array_to_str(sample_rates):
111 return ",".join([str(a)
for a
in sample_rates])
113 def sample_rates_str_to_array(sample_rates_str):
114 return numpy.array([int(a)
for a
in sample_rates_str.split(
',')])
117 def get_fir_matrix(xmldoc, fFinal=None, pnorder=4, flower = 40, psd_interp=None, autocorrelation_length=101, verbose=False):
118 sngl_inspiral_table = lsctables.table.get_table(xmldoc, lsctables.SnglInspiralTable.tableName)
119 fFinal = max(sngl_inspiral_table.getColumnByName(
"f_final"))
120 sampleRate = int(2**(numpy.ceil(numpy.log2(fFinal)+1)))
121 flower = param.get_pyvalue(xmldoc,
'flower')
122 if verbose:
print >> sys.stderr,
"f_min = %f, f_final = %f, sample rate = %f" % (flower, fFinal, sampleRate)
127 if not (autocorrelation_length % 2):
128 raise ValueError,
"autocorrelation_length must be odd (got %d)" % autocorrelation_length
129 autocorrelation_bank = numpy.zeros((len(sngl_inspiral_table), autocorrelation_length), dtype =
"cdouble")
131 for tmp, row
in enumerate(sngl_inspiral_table):
136 amp, phase, f = waveform(m1, m2, flower, fFinal, sampleRate)
137 if psd_interp
is not None:
138 amp /= psd_interp(f)**0.5 * 1e23
140 length = int(2**numpy.ceil(numpy.log2(amp.shape[0])))
141 out = amp * numpy.exp(1j * phase)
144 vec1 = numpy.zeros(length * 2, dtype=numpy.cdouble)
145 vec1[-len(out):] = out
146 norm1 = (1.0/numpy.sqrt(2.0))*((vec1 * numpy.conj(vec1)).sum()**0.5)
151 Mlist.append(vec1.real)
152 Mlist.append(vec1.imag)
160 max_len = max([len(i)
for i
in Mlist])
161 M = numpy.zeros((len(Mlist), max_len))
163 for i, Am
in enumerate(Mlist): M[i,:len(Am)] = Am
165 return M, autocorrelation_bank
167 def compute_autocorrelation_mask( autocorrelation ):
169 Given an autocorrelation time series, estimate the optimal
170 autocorrelation length to use and return a matrix which masks
171 out the unwanted elements. FIXME TODO for now just returns
174 return numpy.ones( autocorrelation.shape, dtype=
"int" )
177 def makeiirbank(xmldoc, sampleRate = None, padding=1.1, epsilon=0.02, alpha=.99, beta=0.25, pnorder=4, flower = 40, psd_interp=None, output_to_xml = False, autocorrelation_length=201, downsample=False, verbose=False):
179 sngl_inspiral_table=lsctables.table.get_table(xmldoc, lsctables.SnglInspiralTable.tableName)
180 fFinal = max(sngl_inspiral_table.getColumnByName(
"f_final"))
181 if sampleRate
is None:
182 sampleRate = int(2**(numpy.ceil(numpy.log2(fFinal)+1)))
184 if verbose:
print >> sys.stderr,
"f_min = %f, f_final = %f, sample rate = %f" % (flower, fFinal, sampleRate)
193 if autocorrelation_length
is not None:
194 if not (autocorrelation_length % 2):
195 raise ValueError,
"autocorrelation_length must be odd (got %d)" % autocorrelation_length
196 autocorrelation_bank = numpy.zeros((len(sngl_inspiral_table), autocorrelation_length), dtype =
"cdouble")
197 autocorrelation_mask = compute_autocorrelation_mask( autocorrelation_bank )
199 autocorrelation_bank =
None
200 autocorrelation_mask =
None
203 for tmp, row
in enumerate(sngl_inspiral_table):
208 if verbose: start = time.time()
216 amp, phase, f = waveform(m1, m2, flower, fFinal, sampleRate)
218 print >> sys.stderr,
"waveform %f (T = %f)" % ((time.time() - start), float(amp.shape[0]/(float(sampleRate))))
220 if psd_interp
is not None:
221 amp /= psd_interp(f)**0.5
224 a1, b0, delay = spawaveform.iir(amp, phase, epsilon, alpha, beta, padding)
226 print >> sys.stderr,
"create IIR bank %f" % (time.time() - start)
229 length = int(2**numpy.ceil(numpy.log2(amp.shape[0]+autocorrelation_length)))
230 if verbose:
print >> sys.stderr,
"length = %d, amp length = %d, autocorrelation length = %d" % (length, amp.shape[0], autocorrelation_length)
233 out = spawaveform.iirresponse(length, a1, b0, delay)
235 print >> sys.stderr,
"create IIR response %f" % (time.time() - start)
238 u = numpy.zeros(length * 1, dtype=numpy.cdouble)
240 norm1 = 1.0/numpy.sqrt(2.0)*((u * numpy.conj(u)).sum()**0.5)
247 out2 = amp * numpy.exp(1j * phase)
248 h = numpy.zeros(length * 1, dtype=numpy.cdouble)
249 h[-len(out2):] = out2
254 norm2 = abs(numpy.dot(h, numpy.conj(h)))
255 h *= numpy.sqrt(2 / norm2)
256 if output_to_xml: row.sigmasq = 1.0 * norm2 / sampleRate
258 newsigma = sigmasq2(row.mchirp, flower, fFinal, psd_interp)
259 print>>sys.stderr,
"norm2 = %e, sigma = %f, %f, %f" % (norm2, numpy.sqrt(row.sigmasq), newsigma, (numpy.sqrt(row.sigmasq)- newsigma)/newsigma)
260 print>>sys.stderr,
"mchirp %fm, fFinal %f, row.f_final %f" % (row.mchirp, fFinal, row.f_final)
264 autocorrelation_bank[tmp,:] = crosscorr(h, h, autocorrelation_length)/2.0
266 print>>sys.stderr,
"auto correlation %f" % ((time.time() - start))
270 snr = abs(numpy.dot(u, numpy.conj(h)))/2.0
272 print>>sys.stderr,
"dot product %f" % ((time.time() - start))
275 if verbose:
print>>sys.stderr,
"row %4.0d, m1 = %10.6f m2 = %10.6f, %4.0d filters, %10.8f match" % (tmp+1, m1,m2,len(a1), snr)
279 if output_to_xml: row.snr = snr
282 fs = -1. * numpy.angle(a1) / 2 / numpy.pi
289 for i, f
in enumerate(fs):
290 M = int(max(1, 2**-numpy.ceil(numpy.log2(f * 2.0 * padding))))
291 a1dict.setdefault(sampleRate/M, []).append(a1[i]**M)
292 newdelay = numpy.ceil((delay[i]+1)/(float(M)))
293 b0dict.setdefault(sampleRate/M, []).append(b0[i]*M**0.5*a1[i]**(newdelay*M-delay[i]))
294 delaydict.setdefault(sampleRate/M, []).append(newdelay)
298 a1dict[int(sampleRate)] = a1
299 b0dict[int(sampleRate)] = b0
300 delaydict[int(sampleRate)] = delay
303 for k
in a1dict.keys():
304 Amat.setdefault(k, []).append(a1dict[k])
305 Bmat.setdefault(k, []).append(b0dict[k])
306 Dmat.setdefault(k, []).append(delaydict[k])
310 if verbose:
print>>sys.stderr,
"filters per sample rate (rate , num filters)\n",[(k,len(v))
for k,v
in a1dict.items()]
318 max_rows = max([len(Amat[rate])
for rate
in Amat.keys()])
319 for rate
in Amat.keys():
320 sample_rates.append(rate)
322 max_len = max([len(i)
for i
in Amat[rate]])
323 DmatMin = min([min(elem)
for elem
in Dmat[rate]])
324 DmatMax = max([max(elem)
for elem
in Dmat[rate]])
325 if verbose:
print>>sys.stderr,
"rate %d, dmin %d, dmax %d, max_row %d, max_len %d" % (rate, DmatMin, DmatMax, max_rows, max_len)
326 A[rate] = numpy.zeros((max_rows, max_len), dtype=numpy.complex128)
327 B[rate] = numpy.zeros((max_rows, max_len), dtype=numpy.complex128)
328 D[rate] = numpy.zeros((max_rows, max_len), dtype=numpy.int)
329 D[rate].fill(DmatMin)
331 for i, Am
in enumerate(Amat[rate]): A[rate][i,:len(Am)] = Am
332 for i, Bm
in enumerate(Bmat[rate]): B[rate][i,:len(Bm)] = Bm
333 for i, Dm
in enumerate(Dmat[rate]): D[rate][i,:len(Dm)] = Dm
339 root = xmldoc.childNodes[0]
340 root.appendChild(array.from_array(
'a_%d' % (rate), repack_complex_array_to_real(A[rate])))
341 root.appendChild(array.from_array(
'b_%d' % (rate), repack_complex_array_to_real(B[rate])))
342 root.appendChild(array.from_array(
'd_%d' % (rate), D[rate]))
345 root = xmldoc.childNodes[0]
346 root.appendChild(param.new_param(
'sample_rate', types.FromPyType[str], sample_rates_array_to_str(sample_rates)))
347 root.appendChild(param.new_param(
'flower', types.FromPyType[float], flower))
348 root.appendChild(param.new_param(
'epsilon', types.FromPyType[float], epsilon))
349 root.appendChild(array.from_array(
'autocorrelation_bank_real', autocorrelation_bank.real))
350 root.appendChild(array.from_array(
'autocorrelation_bank_imag', -autocorrelation_bank.imag))
351 root.appendChild(array.from_array(
'autocorrelation_mask', autocorrelation_mask))
353 return A, B, D, snrvec
355 def crosscorr(a, b, autocorrelation_length = 201):
358 corr = scipy.ifft( af * numpy.conj( bf ))
359 return numpy.concatenate((corr[-(autocorrelation_length // 2):],corr[:(autocorrelation_length // 2 + 1)]))
361 def innerproduct(a,b):
364 a.append(zeros(n/2),complex)
365 a.extend(zeros(n/2),complex)
367 b.append(zeros(n/2),complex)
368 b.extend(zeros(n/2),complex)
378 def smooth_and_interp(psd, width=1, length = 10):
380 f = numpy.arange(len(psd.data)) * psd.deltaF
382 x = numpy.arange(-width*length, width*length)
383 sfunc = numpy.exp(-x**2 / 2.0 / width**2) / (2. * numpy.pi * width**2)**0.5
384 out = numpy.zeros(ln)
385 for i,d
in enumerate(data[width*length:ln-width*length]):
386 out[i+width*length] = (sfunc * data[i:i+2*width*length]).sum()
387 return interpolate.interp1d(f, out)
389 def get_matrices_from_xml(xmldoc):
391 sample_rates = [int(r)
for r
in param.get_pyvalue(root,
'sample_rate').split(
',')]
395 for sr
in sample_rates:
396 A[sr] = repack_real_array_to_complex(array.get_array(root,
'a_%d' % (sr,)).array)
397 B[sr] = repack_real_array_to_complex(array.get_array(root,
'b_%d' % (sr,)).array)
398 D[sr] = array.get_array(root,
'd_%d' % (sr,)).array
399 autocorrelation_bank_real = array.get_array(root,
'autocorrelation_bank_real').array
400 autocorrelation_bank_imag = array.get_array(root,
'autocorrelation_bank_imag').array
401 autocorrelation_bank = autocorrelation_bank_real + (0+1j) * autocorrelation_bank_imag
402 autocorrelation_mask = array.get_array(root,
'autocorrelation_mask').array
404 sngl_inspiral_table=lsctables.table.get_table(xmldoc, lsctables.SnglInspiralTable.tableName)
405 sigmasq = sngl_inspiral_table.getColumnByName(
"sigmasq").asarray()
407 return A, B, D, autocorrelation_bank, autocorrelation_mask, sigmasq
410 def __init__(self, bank_xmldoc, snr_threshold, logname = None, verbose = False):
415 self.A, self.B, self.D, self.autocorrelation_bank, self.autocorrelation_mask, self.
sigmasq = get_matrices_from_xml(bank_xmldoc)
418 def get_rates(self, verbose = False):
419 bank_xmldoc = utils.load_filename(self.
template_bank_filename, contenthandler = XMLContentHandler, verbose = verbose)
420 return [int(r)
for r
in param.get_pyvalue(bank_xmldoc,
'sample_rate').split(
',')]
424 def set_template_bank_filename(self,name):
427 def load_iirbank(filename, snr_threshold, contenthandler = XMLContentHandler, verbose = False):
428 bank_xmldoc = utils.load_filename(filename, contenthandler = contenthandler, verbose = verbose)
430 bank = Bank.__new__(Bank)
437 bank.set_template_bank_filename(filename)