Package pylal :: Module plotsegments
[hide private]
[frames] | no frames]

Source Code for Module pylal.plotsegments

  1  # encoding: utf-8 
  2  # 
  3  # Copyright (C) 2008  Nickolas V Fotopoulos 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify it 
  6  # under the terms of the GNU General Public License as published by the 
  7  # Free Software Foundation; either version 2 of the License, or (at your 
  8  # option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 13  # Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License along 
 16  # with this program; if not, write to the Free Software Foundation, Inc., 
 17  # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
 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  # Plotting class 
 33   
34 -class PlotSegmentsPlot(object):
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
47 - def __init__(self, t0=0):
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
82 - def set_window(self, window_seg, padding=0):
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
96 - def highlight_segment(self, seg):
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
103 - def finalize(self):
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
116 - def close(self):
117 pylab.close(self.fig)
118
119 - def __del__(self):
120 self.close()
121 122 # ============================================================================= 123 # Plot segments 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 # get time limits 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 # get unit for plot 179 unit, timestr = plotutils.time_axis_unit(end-start) 180 181 # set xlabel and renomalize time 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 # get other parameters 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 # escape underscores for latex text 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 # generate plot 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 # highlight segments 228 if highlight_segments: 229 for seg in highlight_segments: 230 plot.highlight_segment(seg) 231 232 # add colorbar 233 if hidden_colorbar: 234 plotutils.add_colorbar(plot.ax, visible=False) 235 236 # set axis limits 237 xlim = [float(start-t0)/unit, float(end-t0)/unit] 238 plot.ax.set_xlim(*xlim) 239 240 # set grid 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 # save 246 plot.savefig(outfile, bbox_inches=bbox_inches,\ 247 bbox_extra_artists=plot.ax.texts) 248 plot.close()
249 250 # ============================================================================= 251 # Plot segment histogram 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 # get limits 296 xlim = kwargs.pop('xlim', None) 297 ylim = kwargs.pop('ylim', None) 298 299 # get labels 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 # get axis scale 306 logx = kwargs.pop('logx', False) 307 logy = kwargs.pop('logy', False) 308 309 # get savefig option 310 bbox_inches = kwargs.pop('bbox_inches', 'tight') 311 hidden_colorbar = kwargs.pop("hidden_colorbar", False) 312 313 # escape underscores for latex text 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 # generate plot object 325 plot = plotutils.VerticalBarHistogram(xlabel, ylabel, title, subtitle) 326 327 # add each segmentlist 328 for flag in keys: 329 plot.add_content([float(abs(seg)) for seg in segdict[flag]],\ 330 label=flag, **kwargs) 331 332 # finalize plot with histograms 333 plot.finalize(num_bins=num_bins, logx=logx, logy=logy) 334 335 # set limits 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 # save figure 343 plot.savefig(outfile, bbox_inches=bbox_inches,\ 344 bbox_extra_artists=plot.ax.texts) 345 plot.close()
346 347 # ============================================================================= 348 # Plot duty cycle 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 # get time limits 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 # get unit for plot 372 unit, timestr = plotutils.time_axis_unit(end-start) 373 374 # set xlabel and renomalize time 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 # get other parameters 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 # escape underscores for latex text 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 # generate duty cycle info 420 # 421 422 # generate bins 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 # generate plot 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 # add running mean 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 # add colorbar 468 if hidden_colorbar: 469 plotutils.add_colorbar(plot.ax, visible=False) 470 471 # set limits 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 # set grid 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 # save figure 483 plot.savefig(outfile, bbox_inches=bbox_inches,\ 484 bbox_extra_artists=plot.ax.texts)
485