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

Source Code for Module pylal.mvsc_plots

  1  #!/usr/bin/python 
  2  """Contains functions to create various plots from lalapps_mvsc_player""" 
  3   
  4  __author__ = 'Tristan Miller <tmiller@caltech.edu>' 
  5  __prog__ = 'mvsc_plots' 
  6   
  7  ############################################################################## 
  8  # import modules 
  9  import math,re 
 10  from matplotlib import pyplot 
 11  from matplotlib import cbook 
 12   
 13  ############################################################################## 
 14   
15 -def patread(filename,station=None,readpat=False,readstr=False,\ 16 headeronly=False,colsonly=False):
17 """Reads in a file from SprOutputWriterApp. 18 19 If readpat is false, reads a dat file. Otherwise, reads a pat file. 20 If headeronly is true, only outputs header in a list. 21 If cols only is true, only outputs header in dict. 22 If station is given, outputs two dicts, the first with more standardized 23 names (ie 'H1L1' => 't1t2') 24 If readstr is false, reads floats. Otherwise, reads strings (which keeps 25 full precision).""" 26 27 try: 28 f = open(filename) 29 except IOError: 30 print '***Error!*** Trouble opening file', filename 31 return 32 33 p = re.compile(r'\S+') 34 35 if readpat: 36 h = f.readline() 37 38 h = f.readline() 39 header = p.findall(h) 40 41 if headeronly: 42 f.close() 43 return header 44 45 cols = {} 46 for i in range(len(header)): 47 cols[header[i]] = i 48 49 if station: 50 iter = cols.iterkeys() 51 cols2 = {} 52 53 while True: 54 try: 55 key = iter.next() 56 origcopy = key 57 58 for j in range(0,6,2): 59 for i in range(0,len(station),2): 60 if key[j:j+2] == station[i:i+2]: 61 key = key[:j]+'t'+str(i/2+1)+key[j+2:] 62 break 63 64 cols2[key] = cols[origcopy] 65 66 except StopIteration: 67 break 68 69 if colsonly: 70 f.close() 71 if station: 72 return cols2,cols 73 else: 74 return cols 75 76 #read the rest of the file 77 78 data = [] 79 if readstr: 80 n = f.readline() 81 m = p.findall(n) 82 if m: 83 for i in range(len(m)): 84 data.append([m[i]]) 85 86 while m: 87 n = f.readline() 88 m = p.findall(n) 89 if m: 90 for i in range(len(m)): 91 data[i].append(m[i]) 92 else: 93 n = f.readline() 94 m = p.findall(n) 95 if m: 96 for i in range(len(m)): 97 data.append([float(m[i])]) 98 99 while m: 100 n = f.readline() 101 m = p.findall(n) 102 if m: 103 for i in range(len(m)): 104 data[i].append(float(m[i])) 105 106 f.close() 107 108 print 'Finished reading file', filename 109 110 if station: 111 return data, cols2, cols 112 else: 113 return data,cols
114 115 ############################################################################## 116
117 -def inforead(filename):
118 """Reads the printout of SprBaggerDecisionTreeApp and returns info. 119 120 Info returned: List of FOM values 121 Table of number of tree splits 122 Number of timeslides in training set 123 Number of injections in training set 124 Number of timeslides in validation set 125 Number of injections in validation set""" 126 127 try: 128 f = open(filename) 129 except IOError: 130 print '***Error!*** Trouble opening file', filename 131 return 132 133 output = [] 134 p1 = re.compile(r'Points in class [0(1):]{5} (\S+)') 135 counter = 0 136 137 while True: 138 n = f.readline() 139 m = p1.match(n) 140 if m: 141 output.append(int(m.group(1))) 142 counter += 1 143 elif counter >= 4: 144 break 145 elif not n: 146 print '***Error!*** Missing info in ', filename 147 return 148 149 p2 = re.compile(r'Validation FOM=(\S+)') 150 fom = [] 151 flag = False 152 while True: 153 n = f.readline() 154 m = p2.match(n) 155 if m: 156 fom.append(float(m.group(1))) 157 flag = True 158 elif flag: 159 break 160 elif not n: 161 print '***Error!*** No FOM in ', filename 162 return 163 164 treesplits=[] 165 p3 = re.compile(r'Variable\s+(\S+)\s+Splits\s+(\S+)\s+Delta FOM\s+(\S+)') 166 while True: 167 n = f.readline() 168 m = p3.match(n) 169 if m: 170 treesplits.append([]) 171 treesplits[-1].append(m.group(1)) 172 treesplits[-1].append(int(m.group(2))) 173 treesplits[-1].append(float(m.group(3))) 174 elif not n: 175 break 176 177 f.close() 178 return fom,treesplits,output[0],output[1],output[2],output[3]
179 180 ############################################################################## 181
182 -def rewrite_results( patpath, resultpath ):
183 """Rewrites the output of SprOutputWriterApp because it couldn't be 184 bothered to save the numbers to full precision. 185 186 Returns the data (so that you don't have to reread the file later)""" 187 188 patdata,patcols = patread(patpath,readpat=True,readstr=True) 189 190 resultdata,resultcols = patread(resultpath) 191 header = patread(resultpath,headeronly=True) 192 193 try: 194 f = open(resultpath,'w') 195 except IOError: 196 print '***Error!*** Trouble opening file', filename 197 return 198 199 for i in range(len(header)): 200 f.write(header[i] + ' ') 201 202 baggercol = resultcols['Bagger'] 203 for i in range(len(patdata[0])): 204 f.write('\n') 205 206 for j in range(3): 207 f.write(str(resultdata[j][i]) + ' ') 208 209 for j in range(len(patdata)-1): 210 f.write(patdata[j][i] + ' ') 211 212 f.write(str(resultdata[baggercol][i])) 213 214 f.close() 215 216 return resultdata
217 218 ############################################################################## 219
220 -def sort_inj_ts(data):
221 """Sorts data into injections and timeslides""" 222 223 injections = [] 224 timeslides = [] 225 for i in range(len(data)): 226 injections.append([]) 227 timeslides.append([]) 228 229 for i in range(len(data[0])): 230 if data[1][i] == 0: 231 for j in range(len(data)): 232 timeslides[j].append(data[j][i]) 233 else: 234 for j in range(len(data)): 235 injections[j].append(data[j][i]) 236 237 return injections,timeslides
238 239 ############################################################################## 240
241 -def ROC(timeslides,injections):
242 """Computes true and false positive rates. 243 244 May change the order of timeslides and injections.""" 245 246 timeslides.sort() 247 injections.sort() 248 n = len(injections) 249 m = len(timeslides) 250 251 truepos = [] 252 falsepos = [] 253 254 for i in range(n): 255 if injections[i] != injections[i-1]: 256 for y in range(n): 257 if injections[y]>injections[i]: 258 truepos.append(1-(y-1)/float(n)) 259 break 260 else: 261 truepos.append(0.0) 262 263 #Note that the minimum false positive rate is set to 1/(m+1) 264 #which is the best upper bound of the wilson confidence interval 265 266 if timeslides[-1]<=injections[i]: 267 falsepos.append(1/float(m+1)) 268 else: 269 for x in range(2,m+1): 270 if timeslides[-x]<=injections[i]: 271 falsepos.append((x-1)/float(m)) 272 break 273 else: 274 falsepos.append(1.0) 275 276 return truepos, falsepos
277 278 ############################################################################## 279
280 -def wilson(p,n):
281 """Calculates the Wilson interval, the confidence interval for a binomial 282 distribution. 283 284 Returns the appropriate upper and lower error bars. 285 The confidence level used is always 68%.""" 286 287 n = float(n) 288 diff = math.sqrt(max(p*(1-p)/n + 0.25/n**2,0)) / (1+1/n) 289 mid = (-p/n + 0.5/n) / (1+1/n) 290 upper = mid+diff 291 lower = diff-mid 292 293 return upper,lower
294 295 ############################################################################## 296
297 -def stairs(x,y):
298 """Transforms lists (x,y) into (x1,y1) such that plotting them will 299 create a stairs graph.""" 300 301 x1 = [] 302 y1 = [y[0]] 303 for i in range(len(x)-1): 304 x1.append(x[i]) 305 x1.append(x[i]) 306 y1.append(y[i+1]) 307 y1.append(y[i+1]) 308 x1.append(x[-1]) 309 310 return x1,y1
311 312 ############################################################################## 313
314 -def top_events(data,cols,n,stations, mvsc_to_fan=None):
315 """Finds the n events with the highest MVSC values. 316 317 If multiple events tie for last, all will be included. 318 Must give data in string form to keep precision. 319 If given mvsc_to_fan (which is [list of mvsc cutoff values, list of 320 corresponding false alarm numbers]), then will add a column of FAN.""" 321 322 baggercol = cols['Bagger'] 323 324 #must transpose data in order to sort it 325 #also, change Bagger column from string to number 326 327 data2 = [] 328 for i in range(len(data[0])): 329 data2.append([]) 330 for j in range(len(data)): 331 if j == baggercol: 332 data2[-1].append(float(data[j][i])) 333 else: 334 data2[-1].append( data[j][i] ) 335 336 sorter = cbook.Sorter() 337 sorter(data2,baggercol) 338 mvsc_cutoff = data2[-min(len(data2),n)][baggercol] 339 340 events = [] 341 index = [] 342 343 for i in range(1,len(data2)+1): 344 if data2[-i][baggercol] >= mvsc_cutoff: 345 index.append(i) 346 events.append([]) 347 for j in range(len(data2[0])): 348 events[-1].append(data2[-i][j]) 349 else: 350 break 351 352 if mvsc_to_fan: 353 #add extra column to 'cols' dict 354 cols['FAN'] = len(cols) 355 356 for i in range(len(events)): 357 mvsc_cutoff = events[i][baggercol] 358 359 for j in range(1,len(mvsc_to_fan[0])+1): 360 if mvsc_to_fan[0][-j] <= mvsc_cutoff: 361 break 362 363 events[i].append(mvsc_to_fan[1][-j]) 364 365 return events
366 367 ############################################################################## 368
369 -def ROCplot(data_inj,data_ts,cols,op_point = 1,ts_trig_ratio = 25):
370 """Creates an ROC plot from one file. 371 372 Returns the confidence interval of the resulting efficiency.""" 373 374 timeslides = data_ts[cols['Bagger']][:] 375 injections = data_inj[cols['Bagger']][:] 376 timeslides_snr = [] 377 injections_snr = [] 378 379 effsnr1 = cols['t1get_effective_snr()'] 380 effsnr2 = cols['t2get_effective_snr()'] 381 382 for i in range(len(data_ts[0])): 383 timeslides_snr.append(data_ts[effsnr1][i]**2+ \ 384 data_ts[effsnr2][i]**2) 385 for i in range(len(data_inj[0])): 386 injections_snr.append(data_inj[effsnr1][i]**2+ \ 387 data_inj[effsnr2][i]**2) 388 389 truepos,falsepos = ROC(timeslides,injections) 390 truepos_snr,falsepos_snr = ROC(timeslides_snr,injections_snr) 391 392 binomerru = [] 393 binomerrl = [] 394 for i in range(len(truepos)): 395 upper,lower = wilson( truepos[i], len(injections) ) 396 binomerru.append(upper) 397 binomerrl.append(lower) 398 binomerru.append(0) 399 binomerrl.append(0) 400 t = binomerru.pop() 401 t = binomerrl.pop() 402 403 binomerru_snr = [] 404 binomerrl_snr = [] 405 for i in range(len(truepos_snr)): 406 upper,lower = wilson( truepos_snr[i], len(injections) ) 407 binomerru_snr.append(upper) 408 binomerrl_snr.append(lower) 409 binomerru_snr.append(0) 410 binomerrl_snr.append(0) 411 t = binomerru_snr.pop() 412 t = binomerrl_snr.pop() 413 414 falsepos2 = [] 415 falsepos2_snr = [] 416 for i in range(len(falsepos)): 417 falsepos2.append( falsepos[i]*float(len(timeslides))/ts_trig_ratio ) 418 for i in range(len(falsepos_snr)): 419 falsepos2_snr.append( falsepos_snr[i]*float(len(timeslides))/ \ 420 ts_trig_ratio ) 421 422 falsepos1,truepos1 = stairs(falsepos2,truepos) 423 falsepos1_snr,truepos1_snr = stairs(falsepos2_snr,truepos_snr) 424 425 pyplot.figure() 426 pyplot.errorbar(falsepos1,truepos1,yerr=[binomerrl,binomerru] \ 427 ,label='MVSC',color='green',linewidth=2) 428 pyplot.errorbar(falsepos1_snr,truepos1_snr,yerr=[binomerrl_snr, \ 429 binomerru_snr], label='Effective SNR', \ 430 color='blue',linewidth=2) 431 pyplot.semilogx() 432 pyplot.xlabel('False alarm number') 433 pyplot.ylabel('True positive rate') 434 pyplot.title('ROC curve') 435 436 op_point = max(op_point,1/(float(len(timeslides)))) 437 pyplot.plot([op_point,op_point],[.85,1.01],'r',label='Operating point') 438 439 for i in range(len(falsepos)): 440 if falsepos2[i] <= op_point: 441 break 442 443 xmin,xmax = pyplot.xlim() 444 mid = truepos[i] 445 upper = mid + binomerru[2*i] 446 lower = mid - binomerrl[2*i] 447 pyplot.plot([xmin,xmax],[mid,mid],'r') 448 pyplot.plot([xmin,xmax],[lower,lower],'r:') 449 pyplot.plot([xmin,xmax],[upper,upper],'r:') 450 451 pyplot.xlim(xmin,xmax) 452 453 pyplot.ylim(.85,1.01) 454 pyplot.legend(loc='lower right') 455 456 return lower,upper
457 458 ############################################################################## 459
460 -def FOMplot(fom):
461 """Plots FOM vs bagger cycle.""" 462 463 pyplot.figure() 464 pyplot.plot(fom) 465 pyplot.xlabel('Bagger cycle') 466 pyplot.ylabel('Figure of Merit') 467 pyplot.title('Figure of Merit vs number of Bagger cycles') 468 pyplot.xlim(-len(fom)*0.05,len(fom))
469 470 ############################################################################## 471
472 -def mvsc_vs_effsnr(data_inj,data_ts,cols, mvsc_cutoff=None,effsnr_cutoff=None,\ 473 zerodata=None):
474 """Plots mvsc values vs the sum of the squares of effective snr.""" 475 476 timeslides = data_ts[cols['Bagger']][:] 477 injections = data_inj[cols['Bagger']][:] 478 timeslides_snr = [] 479 injections_snr = [] 480 481 effsnr1 = cols['t1get_effective_snr()'] 482 effsnr2 = cols['t2get_effective_snr()'] 483 484 for i in range(len(data_ts[0])): 485 timeslides_snr.append(data_ts[effsnr1][i]**2+ \ 486 data_ts[effsnr2][i]**2) 487 for i in range(len(data_inj[0])): 488 injections_snr.append(data_inj[effsnr1][i]**2+ \ 489 data_inj[effsnr2][i]**2) 490 491 pyplot.figure() 492 pyplot.semilogy(timeslides,timeslides_snr,'kx',label='Timeslides') 493 pyplot.plot(injections,injections_snr,'r+',mec="red",label='Injections') 494 pyplot.xlabel('MVSC') 495 pyplot.ylabel('Combined effective SNR squared') 496 pyplot.title('MVSC vs Effective SNR') 497 498 if zerodata: 499 zerolag_snr = [] 500 for i in range(len(zerodata[0])): 501 zerolag_snr.append(zerodata[cols['t1get_effective_snr()']][i]**2+ \ 502 zerodata[cols['t2get_effective_snr()']][i]**2 ) 503 504 pyplot.plot(zerodata[cols['Bagger']],zerolag_snr,'*g',mec='g',\ 505 label='Zero Lag' ) 506 507 if mvsc_cutoff: 508 ymin,ymax = pyplot.ylim() 509 pyplot.plot([mvsc_cutoff,mvsc_cutoff],[ymin,ymax],'b',\ 510 label='Operating point cutoff') 511 if effsnr_cutoff: 512 pyplot.plot([-.1,1.1],[effsnr_cutoff,effsnr_cutoff],'b') 513 514 pyplot.xlim(-.1,1.1) 515 pyplot.legend(loc='upper left')
516 517 ############################################################################## 518
519 -def fraction_detected(data_inj,data_ts, cols, afar = None,mvsc_cutoff=None, \ 520 distance=False ):
521 """Graphs the fraction detected vs snr or distance. 522 523 Returns the false alarm rate (afar), the mvsc cutoff and the effsnr 524 cutoff. Graphs vs snr by default, but if distance=True, will graph 525 against distance instead. Requires either the afar or mvsc_cutoff 526 in order to choose operating point.""" 527 528 #set bins 529 530 if distance: 531 minbin = 1. 532 stepfactor = 3 533 maxbin = 1000000000 534 else: 535 #Make histograms based on following snr bins: 536 minbin = 60. 537 stepfactor = 1.2 538 maxbin = 1000 539 540 snrbins = [ minbin ] 541 i = 1 542 while snrbins[-1] <= maxbin: 543 snrbins.append( stepfactor**(i) * snrbins[0] ) 544 i += 1 545 546 #prepare data for sorting 547 548 inj = [] 549 ts = [] 550 baggercol = cols['Bagger'] 551 effsnr1 = cols['t1get_effective_snr()'] 552 effsnr2 = cols['t2get_effective_snr()'] 553 554 if distance: 555 speccol1 = cols['t1eff_distance'] 556 speccol2 = cols['t2eff_distance'] 557 for i in range(len(data_inj[0])): 558 inj.append( ( data_inj[cols['Bagger']][i], \ 559 data_inj[effsnr1][i]**2 + data_inj[effsnr2][i]**2, \ 560 (data_inj[speccol1][i]+ \ 561 data_inj[speccol2][i])**3/8 ) ) 562 else: 563 speccol1 = cols['t1snr'] 564 speccol2 = cols['t2snr'] 565 for i in range(len(data_inj[0])): 566 inj.append( ( data_inj[cols['Bagger']][i], \ 567 data_inj[effsnr1][i]**2 + data_inj[effsnr2][i]**2, \ 568 data_inj[speccol1][i]**2+ \ 569 data_inj[speccol2][i]**2 ) ) 570 571 for i in range(len(data_ts[0])): 572 ts.append( ( data_ts[baggercol][i], \ 573 data_ts[effsnr1][i]**2 + data_ts[effsnr2][i]**2 ) ) 574 575 # sort 576 sorter = cbook.Sorter() 577 ts_mvsc = sorter(ts,0) 578 ts_effsnr = sorter(ts,1) 579 580 if afar: 581 #Determine cutoff values which allow only the given number of false alarms 582 #Check that this is FAR, and not FAN 8/22/09 583 cutoff = int(afar*len(ts)) + 1 584 mvsc_cutoff = ts_mvsc[-cutoff][0] 585 elif mvsc_cutoff: 586 for i in range(1,len(ts_mvsc)+1): 587 if ts_mvsc[-i][0] < mvsc_cutoff: 588 break 589 590 cutoff = i 591 afar = float(cutoff - 1)/len(ts) 592 else: 593 print '***Error*** Must give fraction_detected either an afar value '+\ 594 'or a mvsc_cutoff value' 595 596 effsnr_cutoff = ts_effsnr[-cutoff][1] 597 598 #Determine which injections were detected 599 det_mvsc = [] 600 notdet_mvsc = [] 601 det_effsnr = [] 602 notdet_effsnr = [] 603 for i in range(len(inj)): 604 if inj[i][0] >= mvsc_cutoff: 605 det_mvsc.append(inj[i][2]) 606 else: 607 notdet_mvsc.append(inj[i][2]) 608 609 if inj[i][1] >= effsnr_cutoff: 610 det_effsnr.append(inj[i][2]) 611 else: 612 notdet_effsnr.append(inj[i][2]) 613 614 #Count the number in each bin 615 mvsc_frac = [] 616 effsnr_frac = [] 617 mvsc_erru = [] 618 mvsc_errl = [] 619 effsnr_erru = [] 620 effsnr_errl = [] 621 for i in range(len(snrbins)-1): 622 det_mvsc_total = 0 623 mvsc_total = 0 624 625 for j in range(len(det_mvsc)): 626 if (det_mvsc[j] > snrbins[i]) & (det_mvsc[j] <= snrbins[i+1]): 627 det_mvsc_total += 1 628 for j in range(len(notdet_mvsc)): 629 if (notdet_mvsc[j] > snrbins[i]) & \ 630 (notdet_mvsc[j] <= snrbins[i+1]): 631 mvsc_total += 1 632 633 mvsc_total += det_mvsc_total 634 635 det_effsnr_total = 0 636 effsnr_total = 0 637 638 for j in range(len(det_effsnr)): 639 if (det_effsnr[j] > snrbins[i]) & (det_effsnr[j] <= snrbins[i+1]): 640 det_effsnr_total += 1 641 for j in range(len(notdet_effsnr)): 642 if (notdet_effsnr[j] > snrbins[i]) & \ 643 (notdet_effsnr[j] <= snrbins[i+1]): 644 effsnr_total += 1 645 646 effsnr_total += det_effsnr_total 647 648 #Calculate the fraction detected in each bin: 649 try: 650 mvsc_frac.append(float(det_mvsc_total)/mvsc_total) 651 upper,lower = wilson(float(det_mvsc_total)/mvsc_total, \ 652 mvsc_total ) 653 mvsc_erru.append(upper) 654 mvsc_errl.append(lower) 655 except ZeroDivisionError: 656 mvsc_frac.append(0.5) 657 mvsc_erru.append(0.5) 658 mvsc_errl.append(0.5) 659 try: 660 effsnr_frac.append(float(det_effsnr_total)/effsnr_total) 661 upper,lower = wilson( float(det_effsnr_total)/effsnr_total, \ 662 effsnr_total ) 663 effsnr_erru.append(upper) 664 effsnr_errl.append(lower) 665 except ZeroDivisionError: 666 effsnr_frac.append(0.5) 667 effsnr_erru.append(0.5) 668 effsnr_errl.append(0.5) 669 670 pyplot.figure() 671 pyplot.semilogx() 672 pyplot.errorbar(snrbins[:-1],effsnr_frac,marker='s',linestyle='-', \ 673 yerr=[effsnr_errl,effsnr_erru],label='Effective SNR',mec='blue') 674 pyplot.errorbar(snrbins[:-1],mvsc_frac,marker='*',linestyle='-', \ 675 yerr=[mvsc_errl,mvsc_erru],label='MVSC',mec='green') 676 pyplot.xlim(snrbins[0]/stepfactor**2,snrbins[-1]*stepfactor**2) 677 pyplot.ylim(-.1,1.1) 678 679 if distance: 680 pyplot.xlabel('Effective Volume') 681 pyplot.legend(loc='lower left') 682 else: 683 pyplot.xlabel('Combined SNR squared') 684 pyplot.legend(loc='lower right') 685 686 pyplot.ylabel('Fraction detected') 687 pyplot.title('Fraction of injections detected using different measures') 688 689 return afar,mvsc_cutoff,effsnr_cutoff
690 691 ############################################################################## 692
693 -def snr_vs_chisqr(data_inj,data_ts,cols,afar = 1.0/2000,zerodata=None ):
694 """Plots SNR vs Chi Squared, indicating which triggers were correctly 695 classified, and which were incorrectly classified. 696 697 afar is the allowed false alarm rate in the classification""" 698 699 # prepare data for sorting 700 inj = [] 701 ts = [] 702 baggercol = cols['Bagger'] 703 chisq1 = cols['t1chisq'] 704 chisq2 = cols['t2chisq'] 705 snr1 = cols['t1snr'] 706 snr2 = cols['t2snr'] 707 708 for i in range(len(data_ts[0])): 709 ts.append( ( data_ts[baggercol][i], \ 710 data_ts[chisq1][i]**2+ \ 711 data_ts[chisq2][i]**2, \ 712 data_ts[snr1][i]**2+ \ 713 data_ts[snr2][i]**2 ) ) 714 for i in range(len(data_inj[0])): 715 inj.append( ( data_inj[baggercol][i], \ 716 data_inj[chisq1][i]**2+ \ 717 data_inj[chisq2][i]**2, \ 718 data_inj[snr1][i]**2+ \ 719 data_inj[snr2][i]**2 ) ) 720 721 cutoff = int(afar*len(ts)) + 1 722 723 #Determine cutoff value which allows only the given number of false alarms 724 sorter = cbook.Sorter() 725 ts_mvsc = sorter(ts,0) 726 mvsc_cutoff = ts_mvsc[-cutoff][0] 727 728 #Classify all triggers 729 falsepos_chi = [] 730 falsepos_snr = [] 731 trueneg_chi = [] 732 trueneg_snr = [] 733 truepos_chi = [] 734 truepos_snr = [] 735 falseneg_chi = [] 736 falseneg_snr = [] 737 for i in range(len(ts)): 738 if ts[i][0] >= mvsc_cutoff: 739 falsepos_chi.append(ts[i][1]) 740 falsepos_snr.append(ts[i][2]) 741 else: 742 trueneg_chi.append(ts[i][1]) 743 trueneg_snr.append(ts[i][2]) 744 for i in range(len(inj)): 745 if inj[i][0] >= mvsc_cutoff: 746 truepos_chi.append(inj[i][1]) 747 truepos_snr.append(inj[i][2]) 748 else: 749 falseneg_chi.append(inj[i][1]) 750 falseneg_snr.append(inj[i][2]) 751 752 pyplot.figure() 753 pyplot.loglog(trueneg_snr,trueneg_chi,'xk',label='Filtered timeslides') 754 pyplot.plot(truepos_snr,truepos_chi,'+r',mec='r', \ 755 label='Detected injections') 756 pyplot.plot(falseneg_snr,falseneg_chi,'oc',mec='c', \ 757 label='Missed injections') 758 pyplot.plot(falsepos_snr,falsepos_chi,'sm',mec='m',label='False alarms') 759 760 if zerodata: 761 zero = [] 762 for i in range(len(zerodata[0])): 763 zero.append( ( zerodata[cols['Bagger']][i], 764 zerodata[cols['t1chisq']][i]**2+ \ 765 zerodata[cols['t2chisq']][i]**2, \ 766 zerodata[cols['t1snr']][i]**2+ \ 767 zerodata[cols['t2snr']][i]**2 ) ) 768 769 zeropos_chi = [] 770 zeropos_snr = [] 771 zeroneg_chi = [] 772 zeroneg_snr = [] 773 for i in range(len(zero)): 774 if zero[i][0] >= mvsc_cutoff: 775 zeropos_chi.append(zero[i][1]) 776 zeropos_snr.append(zero[i][2]) 777 else: 778 zeroneg_chi.append(zero[i][1]) 779 zeroneg_snr.append(zero[i][2]) 780 781 pyplot.plot(zeroneg_snr,zeroneg_chi,'xb', \ 782 label='Zero lag (noise)') 783 pyplot.plot(zeropos_snr,zeropos_chi,'*g',mec='g', \ 784 label='Zero lag (signal)') 785 786 pyplot.legend(loc='upper left') 787 pyplot.ylabel('Combined Chisq squared') 788 pyplot.xlabel('Combined SNR squared') 789 pyplot.title('SNR vs Chi Squared')
790 791 ############################################################################## 792
793 -def FARplot(data_ts,cols,zerodata=None,ts_trig_ratio = 25):
794 """Graphs the cumulative number of detections vs MVSC threshold. 795 796 Returns the coordinates of plotted points so that the FAN can be extracted 797 from the MVSC value later.""" 798 799 ts_mvsc = [] 800 801 ts_mvsc = data_ts[cols['Bagger']][:] 802 ts_mvsc.sort() 803 n = len(ts_mvsc) 804 805 far = [] 806 mvsc = [] 807 mvsc_cutoff = 1 808 flag = True 809 810 for i in range(n): 811 if ts_mvsc[i] != ts_mvsc[i-1]: 812 far.append(float(n-i)/ts_trig_ratio) 813 mvsc.append(ts_mvsc[i]) 814 815 if flag & (far[-1] < 1): 816 mvsc_cutoff = mvsc[-1] 817 flag = False 818 819 far2,mvsc2 = stairs(far,mvsc) 820 821 binomerru = [] 822 binomerrl = [] 823 for i in range(len(far)): 824 upper,lower = wilson( (far[i]/n)*ts_trig_ratio, n ) 825 binomerru.append((upper*n)/ts_trig_ratio) 826 binomerrl.append((lower*n)/ts_trig_ratio) 827 binomerru.append(0) 828 binomerrl.append(0) 829 t = binomerru.pop() 830 t = binomerrl.pop() 831 832 pyplot.figure() 833 pyplot.errorbar(mvsc2,far2,yerr=[binomerrl,binomerru], \ 834 label='Expected FAN (based on timeslides)') 835 pyplot.loglog() 836 837 if zerodata: 838 zero_mvsc = zerodata[cols['Bagger']][:] 839 zero_mvsc.sort() 840 m = len(zero_mvsc) 841 842 zerorate = [] 843 zero_mvsc1 = [] 844 845 for i in range(m): 846 if zero_mvsc[i] != zero_mvsc[i-1]: 847 zerorate.append(float(m-i)) 848 zero_mvsc1.append(zero_mvsc[i]) 849 850 zerorate2,zero_mvsc2 = stairs(zerorate,zero_mvsc1) 851 852 zbinomerru = [] 853 zbinomerrl = [] 854 for i in range(len(zerorate)): 855 upper,lower = wilson( zerorate[i]/m, m ) 856 zbinomerru.append(upper*m) 857 zbinomerrl.append(lower*m) 858 zbinomerru.append(0) 859 zbinomerrl.append(0) 860 t = zbinomerru.pop() 861 t = zbinomerrl.pop() 862 863 pyplot.errorbar(zero_mvsc2,zerorate2,yerr=[zbinomerrl,zbinomerru],\ 864 label='cumulative number of zero lags') 865 866 pyplot.legend(loc='lower left') 867 868 xmin,xmax = pyplot.xlim() 869 ymin,ymax = pyplot.ylim() 870 pyplot.plot([xmin,xmax],[1,1],'r') 871 pyplot.plot([mvsc_cutoff,mvsc_cutoff],[ymin,ymax],'r') 872 pyplot.xlim(xmin,xmax) 873 pyplot.ylim(ymin,ymax) 874 875 pyplot.xlabel('MVSC value cutoff') 876 pyplot.title('FAR plot') 877 878 return mvsc_cutoff,[mvsc,far]
879 880 ############################################################################## 881
882 -def IFANplot(data_ts,cols,zerodata,ts_trig_ratio=25):
883 """Plots the inverse false alarm number vs cumulative number of detections. 884 885 Returns false if fails, true if succeeds""" 886 887 ts_mvsc = data_ts[cols['Bagger']][:] 888 ts_mvsc.sort() 889 n = len(ts_mvsc) 890 891 zero_mvsc = zerodata[cols['Bagger']][:] 892 zero_mvsc.sort() 893 m = len(zero_mvsc) 894 895 cumnumber = [] 896 cumnumber_erru = [] 897 cumnumber_errl = [] 898 ifan = [] 899 ifan_erru = [] 900 ifan_errl = [] 901 for i in range(m): 902 if zero_mvsc[i] != zero_mvsc[i-1]: 903 cumnumber.append(float(m-i)) 904 upper,lower = wilson(cumnumber[-1]/m,m) 905 cumnumber_erru.append(upper*m) 906 cumnumber_errl.append(lower*m) 907 908 for j in range(n): 909 if ts_mvsc[j] >= zero_mvsc[i]: 910 break 911 912 ifan.append(ts_trig_ratio/float(n-j)) 913 upper1,lower1 = wilson(float(n-j)/n,n) 914 upper2 = lower1*n/(float(n-j)*(float(n-j)-lower1*n)) 915 lower2 = upper1*n/(float(n-j)*(float(n-j)+upper1*n)) 916 ifan_erru.append(upper2*ts_trig_ratio) 917 ifan_errl.append(lower2*ts_trig_ratio) 918 919 if len(cumnumber_errl) == 0: 920 return False 921 922 pyplot.figure() 923 pyplot.errorbar(ifan,cumnumber,xerr=[ifan_errl,ifan_erru], \ 924 yerr=[cumnumber_errl,cumnumber_erru]) 925 pyplot.loglog() 926 927 ymin,ymax = pyplot.ylim() 928 xmin,xmax = pyplot.xlim() 929 pyplot.plot([xmin,xmax],[1./xmin,1./xmax],'r',alpha=0.5) 930 pyplot.ylim(ymin,ymax) 931 pyplot.xlim(xmin,xmax) 932 933 pyplot.xlabel('Inverse False Alarm Number') 934 pyplot.ylabel('Cumulative Number') 935 pyplot.title('IFAN plot') 936 937 return True
938