Skip to content

Commit b51c263

Browse files
authored
Enhancements/gw (#40)
* new gw-specific version of initialize_llh * add help for gcn num flag * allow call to get_data with start and stop times for gw * write in tests, clean up * globbing trials for gw * corrections to requirements * avoiding getting absurdly long reports in long tws * adding options for 2 week gw followup * script to run 2 week followup given xml * changed label on p-val hist * print exception if error importing FRA * optons to change number of trials * load ps sens, bg trials from /data/ana * adding code to find contours in 2 week case * keep np version fixed to avoid install errors * starting code for CL calc
1 parent b1a686b commit b51c263

File tree

8 files changed

+120
-36
lines changed

8 files changed

+120
-36
lines changed

fast_response/GWFollowup.py

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import matplotlib as mpl
99
mpl.use('agg')
1010
import matplotlib.pyplot as plt
11+
import pickle
1112

1213
from .FastResponseAnalysis import PriorFollowup
1314
from .reports import GravitationalWaveReport
@@ -47,17 +48,13 @@ def run_background_trials(self, month=None, ntrials=1000):
4748
from scipy import sparse
4849
current_rate = self.llh.nbackground / (self.duration * 86400.) * 1000.
4950

50-
#TODO: replace here once done
51-
#closest_rate = sensitivity_utils.find_nearest(np.linspace(6.0, 7.2, 7), current_rate)
52-
rates = [6.0,6.2,6.4,6.8,7.0]
53-
closest_rate = sensitivity_utils.find_nearest(rates, current_rate)
51+
closest_rate = sensitivity_utils.find_nearest(np.linspace(6.0, 7.2, 7), current_rate)
5452
print(f'Loading 2 week bg trials, rate: {closest_rate}')
5553

56-
#bg_trial_dir = '/data/ana/analyses/NuSources/' \
57-
# + '2023_realtime_gw_analysis/fast_response/' \
58-
# + 'precomputed_background/'
59-
#TODO: change to permanent storage once assigned
60-
bg_trial_dir = '/data/user/jthwaites/FastResponseAnalysis/output/trials/glob_trials/'
54+
bg_trial_dir = '/data/ana/analyses/NuSources/' \
55+
+ '2023_realtime_gw_analysis/fast_response/' \
56+
+ 'precomputed_background/'
57+
6158
pre_ts_array = sparse.load_npz(
6259
bg_trial_dir
6360
+ 'gw_precomputed_trials_delta_t_'
@@ -188,7 +185,60 @@ def initialize_llh(self, skipped=None, scramble=False):
188185
llh.set_temporal_model(box)
189186

190187
return llh
188+
189+
def get_best_fit_contour(self, proportions=[0.5,0.9]):
190+
'''Get a contour for the error around the best-fit point
191+
proportions = confidence levels to calculate
192+
-------
193+
Makes a zoomed skymap of the ts-space with contours
194+
'''
195+
if self.tsd is None: return
196+
197+
from . import plotting_utils
198+
#import meander
199+
import seaborn as sns
200+
201+
print('Calculating contour around best-fit TS')
202+
203+
#get threshold TS value for that level in the bg distribution
204+
levels = [np.percentile(self.tsd, 100*(1-proportion)) for proportion in proportions]
205+
sample_points = np.array(hp.pix2ang(self.nside, np.arange(len(self.skymap)))).T
206+
loc=np.array((np.pi/2 - self.ts_scan['dec'], self.ts_scan['ra'])).T
207+
contours_by_level = meander.spherical_contours(loc, self.ts_scan['TS_spatial_prior_0'], levels)
208+
#print(contours_by_level)
209+
210+
thetas = []; phis=[]
211+
for contours in contours_by_level:
212+
for contour in contours:
213+
theta, phi = contour.T
214+
phi[phi<0] += 2.0*np.pi
215+
thetas.append(theta)
216+
phis.append(phi)
217+
218+
#norm_ts = self.ts_scan['TS_spatial_prior_0'] / sum(self.ts_scan['TS_spatial_prior_0'])
219+
#thetas, phis = plotting_utils.plot_contours(proportions, norm_ts)
220+
221+
#make the plot
222+
pdf_palette = sns.color_palette("Blues", 500)
223+
cmap = mpl.colors.ListedColormap(pdf_palette)
224+
225+
plotting_utils.plot_zoom(self.ts_scan['TS_spatial_prior_0'], self.skymap_fit_ra, self.skymap_fit_dec,
226+
"", range = [0,10], reso=3., cmap = cmap)
227+
228+
plotting_utils.plot_color_bar(range=[0,6], cmap=cmap, col_label=r"TS",offset=-50)
229+
cont_ls = ['solid', 'dashed']*(int(len(proportions)/2))
230+
cont_labels=[f'{proportion*100:.0f}/% CL' for proportion in proportions]
231+
232+
for i in range(len(thetas)):
233+
hp.projplot(thetas[i], phis[i], linewidth=2., c='k')#, ls=cont_ls[i], label=cont_labels[i])
191234

235+
plt.scatter(0,0, marker='*', c = 'k', s = 130, label = "Scan Hot Spot")
236+
plt.legend(loc = 2, ncol=1, fontsize = 16, framealpha = 0.95)
237+
238+
plt.savefig(self.analysispath + '/' + self.analysisid + 'ts_contours.png',bbox_inches='tight')
239+
plt.savefig(self.analysispath + '/' + self.analysisid + 'ts_contours.pdf',bbox_inches='tight', dpi=300)
240+
plt.close()
241+
192242
def plot_ontime(self, with_contour=True, contour_files=None):
193243
return super().plot_ontime(with_contour=True, contour_files=contour_files)
194244

@@ -410,15 +460,22 @@ def ps_sens_range(self):
410460
--------
411461
low: float
412462
lowest sensitivity within dec range
413-
high: floaot
463+
high: float
414464
highest sensitivity wihtin dec range
415465
'''
416-
dec_range = np.linspace(-85,85,35)
417-
sens = [1.15, 1.06, .997, .917, .867, .802, .745, .662,
418-
.629, .573, .481, .403, .332, .250, .183, .101,
419-
.035, .0286, .0311, .0341, .0361, .0394, .0418,
420-
.0439, .0459, .0499, .0520, .0553, .0567, .0632,
421-
.0679, .0732, .0788, .083, .0866]
466+
sens_dir = '/data/ana/analyses/NuSources/2023_realtime_gw_analysis/' \
467+
+ 'fast_response/ps_sensitivities'
468+
469+
with open(f'{sens_dir}/ps_sensitivities_deltaT_{self.duration*86400.:.2e}s.pkl','rb') as f:
470+
saved_sens=pickle.load(f)
471+
dec_range=saved_sens['dec']
472+
sens=saved_sens['sens_flux']
473+
#dec_range = np.linspace(-85,85,35)
474+
#sens = [1.15, 1.06, .997, .917, .867, .802, .745, .662,
475+
# .629, .573, .481, .403, .332, .250, .183, .101,
476+
# .035, .0286, .0311, .0341, .0361, .0394, .0418,
477+
# .0439, .0459, .0499, .0520, .0553, .0567, .0632,
478+
# .0679, .0732, .0788, .083, .0866]
422479

423480
src_theta, src_phi = hp.pix2ang(self.nside, self.ipix_90)
424481
src_dec = np.pi/2. - src_theta
@@ -477,13 +534,19 @@ def make_dec_pdf(self):
477534

478535
sinDec_bins = np.linspace(-1,1,30)
479536
bin_centers = (sinDec_bins[:-1] + sinDec_bins[1:]) / 2
480-
481-
dec_range = np.linspace(-1,1,35)
482-
sens = [1.15, 1.06, .997, .917, .867, .802, .745, .662,
483-
.629, .573, .481, .403, .332, .250, .183, .101,
484-
.035, .0286, .0311, .0341, .0361, .0394, .0418,
485-
.0439, .0459, .0499, .0520, .0553, .0567, .0632,
486-
.0679, .0732, .0788, .083, .0866]
537+
sens_dir = '/data/ana/analyses/NuSources/2023_realtime_gw_analysis/' \
538+
+ 'fast_response/ps_sensitivities'
539+
with open(f'{sens_dir}/ps_sensitivities_deltaT_{self.duration*86400.:.2e}s.pkl','rb') as f:
540+
saved_sens=pickle.load(f)
541+
dec_range=np.sin(saved_sens['dec']*np.pi/180)
542+
sens=saved_sens['sens_flux']
543+
544+
#dec_range = np.linspace(-1,1,35)
545+
#sens = [1.15, 1.06, .997, .917, .867, .802, .745, .662,
546+
# .629, .573, .481, .403, .332, .250, .183, .101,
547+
# .035, .0286, .0311, .0341, .0361, .0394, .0418,
548+
# .0439, .0459, .0499, .0520, .0553, .0567, .0632,
549+
# .0679, .0732, .0788, .083, .0866]
487550
sens = np.array(sens)
488551

489552
pixels = np.arange(len(self.skymap))
@@ -530,5 +593,8 @@ def generate_report(self):
530593
r'''Generates report using class attributes
531594
and the ReportGenerator Class'''
532595
report = GravitationalWaveReport(self)
596+
if self.duration > 1.:
597+
report._figure_list = [('decPDF', 'decPDF.png'),('ts_contours', 'ts_contours.png')]
598+
533599
report.generate_report()
534600
report.make_pdf()

fast_response/listeners/gw_gcn_listener.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,17 @@ def process_gcn(payload, root):
5353
for elem in root.iterfind('.//Param')}
5454

5555
# Read trigger time of event
56-
if root.attrib['role'] == 'observation':
57-
eventtime = root.find('.//ISOTime').text
58-
event_mjd = Time(eventtime, format='isot').mjd
59-
else:
56+
eventtime = root.find('.//ISOTime').text
57+
event_mjd = Time(eventtime, format='isot').mjd
58+
59+
if root.attrib['role'] == 'test':
6060
#if testing, want to query livestream rather than load archival, so use recent time
6161
eventtime = '2023-01-13T21:51:25.506'
6262
event_mjd = Time(eventtime, format='isot').mjd - 400./86400.
6363
eventtime = Time(event_mjd, format = 'mjd').isot
64+
else:
65+
eventtime = root.find('.//ISOTime').text
66+
event_mjd = Time(eventtime, format='isot').mjd
6467

6568
print('GW merger time: %s \n' % Time(eventtime, format='isot').iso)
6669
log_file.flush()
@@ -179,7 +182,8 @@ def process_gcn(payload, root):
179182
help='bool to decide if we should run an already unblinded skymap with unblinded data')
180183
args = parser.parse_args()
181184

182-
logfile=args.log_path +'log.log'
185+
logfile=args.log_path +'/log.log'
186+
print(f'Logging to file: {logfile}')
183187
original_stdout=sys.stdout
184188
log_file = open(logfile, "a+")
185189
sys.stdout=log_file
@@ -198,6 +202,7 @@ def process_gcn(payload, root):
198202
#sample_skymap_path='/data/user/jthwaites/o3-gw-skymaps/'
199203
sample_skymap_path=os.path.dirname(fast_response.__file__) +'/sample_skymaps/'
200204
except Exception as e:
205+
print(e)
201206
sample_skymap_path='/data/user/jthwaites/o3-gw-skymaps/'
202207

203208
payload = open(sample_skymap_path+args.test_path, 'rb').read()

fast_response/precomputed_background/glob_precomputed_trials.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def glob_allsky_scans(delta_t, rate, dir, low_stats=False):
5050

5151
return maps
5252

53-
for rate in [6.0, 6.2, 6.4, 6.8, 7.0]: # 6.6, 7.2
53+
for rate in [6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2]:
5454
for low_stats in [True]:#, False]:
5555
print("Rate: {} mHz, low stats: {}".format(rate, low_stats))
5656
maps = glob_allsky_scans(args.deltaT, rate, args.outdir, low_stats=low_stats)

fast_response/precomputed_background/submit_precomputed_trials.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
parser.add_argument(
1515
'--ntrials', type=int, default=30000,
1616
help='Number of precomputed trials to run, default 30,000')
17+
parser.add_argument(
18+
'--seed_start', type=int,default=0,
19+
help='Seed to start with when running trials')
20+
parser.add_argument(
21+
'--n_per_batch', default=100, type=int,
22+
help='Number of trials to run in each set (default: 100)')
1723
args = parser.parse_args()
1824

1925
username = pwd.getpwuid(os.getuid())[0]
@@ -65,13 +71,14 @@
6571
# )
6672

6773
prev_trials = glob.glob('/data/user/jthwaites/FastResponseAnalysis/output/trials/*.npz')
68-
for bg_rate in [7.2]:#[6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2]:
69-
for seed in range(int(args.ntrials/100)):
74+
for bg_rate in [6.6]:#[6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2]:
75+
for seed in range(args.seed_start, int(args.ntrials/args.n_per_batch)):
7076
seed = seed*100
7177
if f'/data/user/jthwaites/FastResponseAnalysis/output/trials/gw_{bg_rate}_mHz_seed_{seed}_delta_t_1.2e+06.npz' not in prev_trials:
7278
#deltaT {args.tw} --ntrials 100 --seed {seed} --bkg {bg}
7379
job.add_arg('--deltaT %s --ntrials %i --seed %i --bkg %s'
74-
%(args.tw, 100, seed, bg_rate))
80+
%(args.tw, args.n_per_batch, seed, bg_rate))
81+
7582

7683
#job.add_child(glob_jobs)
7784

fast_response/scripts/run_external_followup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def run_analysis(args):
4444
f.calc_pvalue(ntrials = args.ntrials)
4545
f.make_dNdE()
4646
f.plot_tsd()
47-
f.upper_limit()
47+
f.upper_limit(n_per_sig = args.n_per_sig)
4848
results = f.save_results()
4949

5050
print("Beginning to make the report")
@@ -80,6 +80,8 @@ def run_analysis(args):
8080
"Example --skip-events=127853:67093193")
8181
parser.add_argument('--ntrials', default=100, type=int,
8282
help="Number of background trials to perform")
83+
parser.add_argument('--n_per_sig', default=100, type=int,
84+
help="Number of signal trials per injected ns to perform")
8385
parser.add_argument('--document', default=False, action='store_true')
8486
args = parser.parse_args()
8587

fast_response/scripts/run_gw_followup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
print('Beginning 2 week NS followup')
4242
start_time = gw_time - 0.1
4343
stop_time = gw_time + 14.
44+
4445
start = start_time.iso
4546
stop = stop_time.iso
4647

@@ -56,6 +57,9 @@
5657
f.calc_pvalue()
5758
f.make_dNdE()
5859
f.plot_tsd(allow_neg=f._allow_neg)
60+
#if delta_t/86400. > 1.:
61+
# f.get_best_fit_contour()
62+
5963
f.upper_limit()
6064
f.find_coincident_events()
6165
f.per_event_pvalue()

fast_response/web_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ def updateFastResponsePlots(gw=False):
253253
p_x_vals = np.logspace(-3,0.,15)
254254
plt.figure(figsize = (10,6), dpi=300)
255255
plt.hist(df['Pre-trial p_val'], weights = np.ones(len(df)) / len(df), bins = p_x_vals)
256-
plt.step(p_x_vals[1:], np.diff(p_x_vals), label = 'Uniform p-value expectation', lw = 3.)
256+
plt.step(p_x_vals[1:], np.diff(p_x_vals), label = 'Uniform p-value distribution', lw = 3.)
257257
plt.xscale('log')
258258
plt.yscale('log')
259259
plt.gca().invert_xaxis()

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ kiwisolver==1.1.0
1111
matplotlib==2.2.5
1212
meander==0.0.3
1313
more-itertools==5.0.0
14-
numpy>=1.21.5
14+
numpy==1.21.5
1515
numexpr==2.8.1
1616
pandas>=1.2.2
1717
pluggy==0.7.1
@@ -28,4 +28,4 @@ six==1.14.0
2828
subprocess32==3.5.4
2929
zmq==0.0.0
3030
py27hash==1.0.2
31-
pygcn>=1.1.2
31+
pygcn==1.1.2

0 commit comments

Comments
 (0)