36 from matplotlib
import figure
37 from matplotlib.backends.backend_agg
import FigureCanvasAgg
as FigureCanvas
39 from gstlal.plotutil
import golden_ratio
40 from glue.ligolw
import lsctables
41 from gstlal.reference_psd
import horizon_distance
43 def plot_psds(psds, coinc_xmldoc = None, plot_width = 640, colours = {"H1":
"r", "H2": "b", "L1": "g", "V1": "m"}):
45 Produces a matplotlib figure of PSDs.
47 @param psds A dictionary of PSDs as REAL8FrequencySeries keyed by
50 @param coinc_xmldoc An XML document containing a single event with all
51 of the metadata as would be uploaded to gracedb. This is optional.
53 @param plot_width How wide to make the plot in pixels
55 @param colours A misspelling of the word "colors" here used to indictate
56 the color of the PSD trace for each instrument
60 if coinc_xmldoc
is not None:
61 coinc_event, = lsctables.CoincTable.get_table(coinc_xmldoc)
62 coinc_inspiral, = lsctables.CoincInspiralTable.get_table(coinc_xmldoc)
63 offset_vector = lsctables.TimeSlideTable.get_table(coinc_xmldoc).as_dict()[coinc_event.time_slide_id]
if coinc_event.time_slide_id
is not None else None
66 sngl_inspirals = dict((row.ifo, row)
for row
in lsctables.SnglInspiralTable.get_table(coinc_xmldoc))
68 mass1 = sngl_inspirals.values()[0].mass1
69 mass2 = sngl_inspirals.values()[0].mass2
70 end_time = coinc_inspiral.get_end()
71 logging.info(
"%g Msun -- %g Msun event in %s at %.2f GPS" % (mass1, mass2,
", ".join(sorted(sngl_inspirals)), float(end_time)))
75 mass1, mass2, end_time = 1.4, 1.4, 0
79 fig.set_size_inches(plot_width / float(fig.get_dpi()), int(round(plot_width / golden_ratio)) / float(fig.get_dpi()))
83 min_psds, max_psds = [], []
84 for instrument, psd
in sorted(psds.items()):
88 f = psd.f0 + numpy.arange(len(psd_data)) * psd.deltaF
89 logging.info(
"found PSD for %s spanning [%g Hz, %g Hz]" % (instrument, f[0], f[-1]))
90 axes.loglog(f, psd_data, color = colours[instrument], alpha = 0.8, label =
"%s (%.4g Mpc)" % (instrument,
horizon_distance(psd, mass1, mass2, 8, 10)))
91 if instrument
in sngl_inspirals:
92 logging.info(
"found %s event with SNR %g" % (instrument, sngl_inspirals[instrument].snr))
93 inspiral_spectrum = [
None,
None]
94 horizon_distance(psd, mass1, mass2, sngl_inspirals[instrument].snr, 10, inspiral_spectrum = inspiral_spectrum)
95 axes.loglog(inspiral_spectrum[0], inspiral_spectrum[1], color = colours[instrument], dashes = (5, 2), alpha = 0.8, label =
"SNR = %.3g" % sngl_inspirals[instrument].snr)
97 min_psds.append(psd_data[int((10.0 - psd.f0) / psd.deltaF) : int((1000 - psd.f0) / psd.deltaF)].min())
99 max_psds.append(psd_data[int((1.0 - psd.f0) / psd.deltaF) : int((1000 - psd.f0) / psd.deltaF)].max())
101 axes.set_xlim((1.0, 3000.0))
103 axes.set_ylim((10**math.floor(math.log10(min(min_psds))), 10**math.ceil(math.log10(max(max_psds)))))
104 axes.set_title(
r"Strain Noise Spectral Density for $%.3g\,\mathrm{M}_{\odot}$--$%.3g\,\mathrm{M}_{\odot}$ Merger at %.2f GPS" % (mass1, mass2, float(end_time)))
105 axes.set_xlabel(
r"Frequency (Hz)")
106 axes.set_ylabel(
r"Spectral Density ($\mathrm{strain}^2 / \mathrm{Hz}$)")
107 axes.legend(loc =
"lower left")