1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 __author__ = "Nickolas Fotopoulos <nvf@gravity.phys.uwm.edu>"
20
21 import datetime, re
22 import numpy
23
24 from warnings import warn
25 from glue import segments
26 from pylal import plotutils
27 from pylal import date
28 from pylal.datatypes import LIGOTimeGPS
29 import pylab
30
31
32
33
35 """
36 Represent a plotsegments plot. To use it, one must instantiate a
37 PlotSegmentsPlot object, call add_contents(), then call finalize().
38 To save, call the savefig() method. To display to the screen, call
39 pylab.show().
40
41 Developer note: There is the transformation function _time_transform.
42 Follow the convention of applying it before storing internal data so that
43 there is no ambiguity about whether data has been transformed or not.
44 """
45 color_code = {'H1':'r', 'H2':'b', 'L1':'g', 'V1':'m', 'G1':'k'}
46
48 """
49 Create a fresh plot. Provide t0 to provide a reference time to use as
50 zero.
51 """
52 warn("This class is now deprecated by pylal.plotutils.SegmentPlot",\
53 DeprecationWarning)
54 self.fig = pylab.figure()
55 self.ax = self.fig.add_subplot(111)
56 self.savefig = self.fig.savefig
57
58 self.window = None
59 self.ifos = []
60 self._time_transform = lambda t: t - t0
61
62 self.ax.set_xlabel("time (s)")
63 self.ax.set_ylabel("IFO")
64
65 - def add_contents(self, segdict, ifos=None):
66 """
67 Add the contents of segdict to the plot. Provide the list ifos, if you
68 wish to specify the order in which they appear or wish to plot a subset of
69 the segmentlists in segdict.
70 """
71 if ifos is None:
72 ifos = segdict.keys()
73 ifos.sort()
74 self.ifos.extend(ifos[::-1])
75 for row, ifo in enumerate(ifos[::-1]):
76 color = self.color_code[ifo]
77 for seg in segdict[ifo]:
78 a = self._time_transform(seg[0])
79 b = self._time_transform(seg[1])
80 self.ax.fill([a, b, b, a, a], [row, row, row+1, row+1, row], color)
81
83 """
84 Define a window of interest by setting the x-limits of the plot
85 appropriately. If padding is also present, protract the x-limits by
86 that quantity and mark the unpadded window with solid black lines.
87 """
88 a = self._time_transform(window_seg[0])
89 b = self._time_transform(window_seg[1])
90 self.window = segments.segment((a - padding, b + padding))
91
92 if padding > 0:
93 self.ax.axvline(a, color='k', linewidth=2)
94 self.ax.axvline(b, color='k', linewidth=2)
95
97 """
98 Highlight a particular segment with dashed lines.
99 """
100 self.ax.axvline(self._time_transform(seg[0]), color='k', linestyle='--')
101 self.ax.axvline(self._time_transform(seg[1]), color='k', linestyle='--')
102
104 """
105 Make final changes to the plot with the guarantee that no additional data
106 will be added.
107 """
108 ticks = pylab.arange(len(self.ifos)) + 0.5
109 self.ax.set_yticks(ticks)
110 self.ax.set_yticklabels(self.ifos)
111
112 if self.window is not None:
113 self.ax.set_xlim(self.window)
114 self.ax.set_ylim((0, len(self.ifos)))
115
118
121
122
123
124
125
126 -def plotsegmentlistdict(segdict, outfile, keys=None, t0=None,\
127 highlight_segments=None, insetlabels=None,\
128 **kwargs):
129 """
130 Plots a glue.segments.segmentlistdict using the PlotSegmentsPlot class from
131 pylal.plotutils.
132
133 Arguments:
134
135 segdict : glue.segments.segmentlistdict
136 dictionary of (name, segmentlist) pairs to plot.
137 outfile : str
138 filepath to write to
139
140 Keyword arguments:
141
142 keys : list
143 ordered list of keys to use in this order on the plot
144 t0 : float
145 GPS time around which to zero plot
146 highlight_segments : glue.segments.segmentlistdict
147 list of segments to highlight with vertical red dashed lines
148 insetlabels : [ True | False ]
149 write labels inside the plot axis
150
151 Unnamed keyword arguments:
152
153 xlabel : string
154 label for x-axis
155 ylabel : string
156 label for y-axis
157 title : string
158 title for plot
159 subtitle : string
160 subtitle for plot
161 bbox_inches : str
162 use "tight" to get a bounding box tight to the axis.
163 """
164
165 xlim = kwargs.pop("xlim", None)
166 if xlim is None:
167 try:
168 extents = [seg.extent() for seg in segdict.values()]
169 start = min(s[0] for s in extents)
170 end = max(s[1] for s in extents)
171 except ValueError:
172 start = 0
173 end = 1
174 xlim = start,end
175 else:
176 start,end = xlim
177
178
179 unit, timestr = plotutils.time_axis_unit(end-start)
180
181
182 xlabel = kwargs.pop("xlabel", None)
183 if not xlabel:
184 if not t0:
185 t0 = start
186 unit, timestr = plotutils.time_axis_unit(end-start)
187 t0 = LIGOTimeGPS(float(t0))
188 if t0.nanoseconds==0:
189 xlabel = datetime.datetime(*date.XLALGPSToUTC(t0)[:6])\
190 .strftime("%B %d %Y, %H:%M:%S %ZUTC")
191 xlabel = "Time (%s) since %s (%s)" % (timestr, xlabel, int(t0))
192 else:
193 xlabel = datetime.datetime(*date.XLALGPSToUTC(\
194 LIGOTimeGPS(t0.seconds))[:6])\
195 .strftime("%B %d %Y, %H:%M:%S %ZUTC")
196 xlabel = "Time (%s) since %s (%s)"\
197 % (timestr,
198 xlabel.replace(" UTC", ".%.3s UTC" % t0.nanoseconds),\
199 t0)
200 t0 = float(t0)
201 ylabel = kwargs.pop("ylabel", "")
202 title = kwargs.pop("title", "")
203 subtitle = kwargs.pop("subtitle", "")
204
205
206 labels_inset = kwargs.pop("labels_inset", False)
207 bbox_inches = kwargs.pop("bbox_inches", "tight")
208 hidden_colorbar = kwargs.pop("hidden_colorbar", False)
209
210
211 if not keys:
212 keys = segdict.keys()
213 if pylab.rcParams["text.usetex"]:
214 newdict = segments.segmentlistdict()
215 for i,key in enumerate(keys):
216 newkey = re.sub('(?<!\\\\)_', '\_', key)
217 keys[i] = newkey
218 newdict[newkey] = segdict[key]
219 segdict = newdict
220
221
222 plot = plotutils.PlotSegmentsPlot(xlabel, ylabel, title, subtitle,\
223 t0=t0, dt=unit)
224 plot.add_content(segdict, keys, **kwargs)
225 plot.finalize(labels_inset=insetlabels)
226
227
228 if highlight_segments:
229 for seg in highlight_segments:
230 plot.highlight_segment(seg)
231
232
233 if hidden_colorbar:
234 plotutils.add_colorbar(plot.ax, visible=False)
235
236
237 xlim = [float(start-t0)/unit, float(end-t0)/unit]
238 plot.ax.set_xlim(*xlim)
239
240
241 plot.ax.grid(True, which="both")
242 plotutils.set_time_ticks(plot.ax)
243 plotutils.set_minor_ticks(plot.ax, x=False)
244
245
246 plot.savefig(outfile, bbox_inches=bbox_inches,\
247 bbox_extra_artists=plot.ax.texts)
248 plot.close()
249
250
251
252
253
254 -def plothistogram(segdict, outfile, keys=None, num_bins=100, **kwargs):
255 """
256 Plots a histogram of segment duration for each entry in the
257 glue.segments.segmentlistdict segdict.
258
259 Arguments:
260
261 segdict : glue.segments.segmentlistdict
262 list of segments with which to veto triggers, use dict for multiple
263 datasets
264 outfile : string
265 string path for output plot
266
267 Keyword arguments:
268
269 keys : [ str | list]
270 ordered list of keys to use in this order on the plot
271 num_bins : int
272 number of bins.
273
274 Unnamed keyword arguments:
275
276 logx : [ True | False ]
277 display x-axis in log scale
278 logy : [ True | False ]
279 display y-axis in log scale
280 xlim : tuple
281 (xmin,xmax) limits for x-axis
282 ylim : tuple
283 (ymin,ymax) limits for y-axis
284 xlabel : string
285 label for x-axis
286 ylabel : string
287 label for y-axis
288 title : string
289 title for plot
290 subtitle : string
291 subtitle for plot
292 bbox_inches : str
293 use "tight" to get a bounding box tight to the axis.
294 """
295
296 xlim = kwargs.pop('xlim', None)
297 ylim = kwargs.pop('ylim', None)
298
299
300 xlabel = kwargs.pop('xlabel', 'Length of segment (seconds)')
301 ylabel = kwargs.pop('ylabel', 'Number of segments')
302 title = kwargs.pop('title', 'Segment Duration Histogram')
303 subtitle = kwargs.pop('subtitle', "")
304
305
306 logx = kwargs.pop('logx', False)
307 logy = kwargs.pop('logy', False)
308
309
310 bbox_inches = kwargs.pop('bbox_inches', 'tight')
311 hidden_colorbar = kwargs.pop("hidden_colorbar", False)
312
313
314 if not keys:
315 keys = segdict.keys()
316 if pylab.rcParams["text.usetex"]:
317 newdict = segments.segmentlistdict()
318 for i,key in enumerate(keys):
319 newkey = re.sub('(?<!\\\\)_', '\_', key)
320 keys[i] = newkey
321 newdict[newkey] = segdict[key]
322 segdict = newdict
323
324
325 plot = plotutils.VerticalBarHistogram(xlabel, ylabel, title, subtitle)
326
327
328 for flag in keys:
329 plot.add_content([float(abs(seg)) for seg in segdict[flag]],\
330 label=flag, **kwargs)
331
332
333 plot.finalize(num_bins=num_bins, logx=logx, logy=logy)
334
335
336 plot.ax.autoscale_view(tight=True, scalex=True, scaley=True)
337 if ylim:
338 plot.ax.set_ylim(map(float, ylim))
339 if xlim:
340 plot.ax.set_xlim(map(float, xlim))
341
342
343 plot.savefig(outfile, bbox_inches=bbox_inches,\
344 bbox_extra_artists=plot.ax.texts)
345 plot.close()
346
347
348
349
350
351 -def plotdutycycle(segdict, outfile, binlength=3600, keys=None, t0=None,\
352 showmean=False, **kwargs):
353 """
354 Plot the percentage duty cycle each flag in the given
355 glue.segments.segmentlistdict, binned over the given duration.
356 """
357
358 xlim = kwargs.pop("xlim", None)
359 if xlim is None:
360 try:
361 extents = [seg.extent() for seg in segdict.values()]
362 start = min(s[0] for s in extents)
363 end = max(s[1] for s in extents)
364 except ValueError:
365 start = 0
366 end = 1
367 xlim = start,end
368 else:
369 start,end = xlim
370
371
372 unit, timestr = plotutils.time_axis_unit(end-start)
373
374
375 xlabel = kwargs.pop("xlabel", None)
376 if not xlabel:
377 if not t0:
378 t0 = start
379 unit, timestr = plotutils.time_axis_unit(end-start)
380 t0 = LIGOTimeGPS(float(t0))
381 if t0.nanoseconds==0:
382 xlabel = datetime.datetime(*date.XLALGPSToUTC(t0)[:6])\
383 .strftime("%B %d %Y, %H:%M:%S %ZUTC")
384 xlabel = "Time (%s) since %s (%s)" % (timestr, xlabel, int(t0))
385 else:
386 xlabel = datetime.datetime(*date.XLALGPSToUTC(\
387 LIGOTimeGPS(t0.seconds))[:6])\
388 .strftime("%B %d %Y, %H:%M:%S %ZUTC")
389 xlabel = "Time (%s) since %s (%s)"\
390 % (timestr,
391 xlabel.replace(" UTC", ".%.3s UTC" % t0.nanoseconds),\
392 t0)
393 t0 = float(t0)
394 xlim[0] = (start - t0)/unit
395 xlim[1] = (end - t0)/unit
396 ylabel = kwargs.pop("ylabel", "")
397 title = kwargs.pop("title", "")
398 subtitle = kwargs.pop("subtitle", "")
399
400
401 loc = kwargs.pop("loc", 0)
402 legalpha = kwargs.pop("alpha", 0.8)
403 labels_inset = kwargs.pop("labels_inset", False)
404 bbox_inches = kwargs.pop("bbox_inches", "tight")
405 hidden_colorbar = kwargs.pop("hidden_colorbar", False)
406
407
408 if not keys:
409 keys = segdict.keys()
410 if pylab.rcParams["text.usetex"]:
411 newdict = segments.segmentlistdict()
412 for i,key in enumerate(keys):
413 newkey = re.sub('(?<!\\\\)_', '\_', key)
414 keys[i] = newkey
415 newdict[newkey] = segdict[key]
416 segdict = newdict
417
418
419
420
421
422
423 binlength = float(binlength)
424 if int(end-start) % binlength == 0:
425 numbins = int(end-start)/binlength
426 else:
427 numbins = float(end-start)//binlength+1
428 bins = numpy.arange(float(start), float(end), binlength) + binlength/2
429 duty = dict((key, numpy.zeros(numbins)) for key in keys)
430
431 bs = float(start)
432 for i in range(numbins):
433 be = float(bs + binlength)
434 seg = segments.segmentlist([segments.segment(bs, be)])
435 for key in keys:
436 duty[key][i] = float(abs(segdict[key] & seg))/abs(seg) * 100
437 bs += binlength
438
439 if showmean:
440 mean = dict((key, numpy.zeros(numbins)) for key in keys)
441 for key in keys:
442 mean[key] = [duty[key][:i+1].mean() for i in range(numbins)]
443
444
445
446
447
448 bins = (bins-t0)/unit
449
450 plot = plotutils.BarPlot(xlabel, ylabel, title, subtitle)
451 for i,key in enumerate(keys):
452 if showmean:
453 thislabel = plotutils.display_name(key) + ' (%.2f\%%)' % (mean[key][-1])
454 else:
455 thislabel = plotutils.display_name(key)
456 plot.add_content(bins, duty[key], label=thislabel,\
457 alpha=0.8, width=binlength/unit)
458 plot.finalize(loc=loc, alpha=legalpha)
459
460
461 if showmean:
462 for i,key in enumerate(keys):
463 print i, key
464 plot.ax.plot(bins, mean[key], linestyle = '--')
465 plot.ax.get_legend().get_frame().set_alpha(0.5)
466
467
468 if hidden_colorbar:
469 plotutils.add_colorbar(plot.ax, visible=False)
470
471
472 plot.ax.autoscale_view(tight=True, scalex=True)
473 if xlim:
474 plot.ax.set_xlim(map(float, xlim))
475 plot.ax.set_ylim(0, 100)
476
477
478 plot.ax.grid(True, which="both")
479 plotutils.set_time_ticks(plot.ax)
480 plotutils.set_minor_ticks(plot.ax, x=False)
481
482
483 plot.savefig(outfile, bbox_inches=bbox_inches,\
484 bbox_extra_artists=plot.ax.texts)
485