def get_gracedb(self, gfile, destination): """ Get a file from Gracedb, and store it in the event repository. Parameters ---------- gfile : str The name of the gracedb file, e.g. `coinc.xml`. destination : str The location in the repository for this file. """ gid = self.meta['gid'] client = GraceDb(service_url=config.get("gracedb", "url")) file_obj = client.files(gid, gfile) with open("download.file", "w") as dest_file: dest_file.write(file_obj.read().decode()) self.repository.add_file("download.file", destination, commit_message = f"Downloaded {gfile} from GraceDB")
'object': { 'comment': 'automatic Omega Scans begun for: chanset1, chanset2.', }, } #------- OmegaScan name = 'omega scan' tests.append((name, alert)) #------------------------ if opts.skymaps: ### set up inputs for fitsname in [ fitsname for fitsname in gdb.files(graceid).json().keys() if fitsname.endswith('.fits') or fitsname.endswith('.fits.gz') ]: alert = { 'alert_type': 'update', 'uid': graceid, ### generate an alert from graceid? Should already be a dicitonary by this point... 'file': fitsname, 'object': { 'tag_names': ['sky_loc'] } } #------- SkymapSanity name = 'skymap sanity' tests.append((name, alert))
def get_event(params): g = GraceDb() eventString = params["event"] events = g.events('%s' % eventString) event = [x for x in events][0] keys = [ 'graceid', 'gpstime', 'extra_attributes', 'group', 'links', 'created', 'far', 'instruments', 'labels', 'nevents', 'submitter', 'search', 'likelihood' ] fileorder = [ 'LALInference_skymap.fits.gz', 'bayestar.fits.gz', 'BW_skymap.fits', 'LIB_skymap.fits.gz', 'skyprobcc_cWB.fits' ] #fileorder = ['LALInference3d.fits.gz','bayestar3d.fits.gz','bayestar.fits.gz'] fileorder = [ 'LALInference_skymap.fits.gz', 'bayestar.fits.gz', 'BW_skymap.fits', 'LIB_skymap.fits.gz', 'skyprobcc_cWB.fits' ] eventinfo = {} for key in keys: if not key in event: continue eventinfo[key] = event[key] eventinfo['gpstime'] = float(eventinfo['gpstime']) if eventinfo['far'] == None: eventinfo['far'] = np.nan triggerfile = "%s/%s.txt" % (params["outputDir"], eventinfo['graceid']) skymapfile = '%s/%s.fits' % (params["outputDir"], eventinfo['graceid']) #if os.path.isfile(triggerfile) and os.path.isfile(skymapfile): # print "Already have info for %s... continuing."%event["graceid"] # return print "Getting info for %s" % event["graceid"] mjds = [-1, -1] timediff = -1 if 'CoincInspiral' in event['extra_attributes']: eventinfo['coinc'] = event['extra_attributes']['CoincInspiral'] if 'SingleInspiral' in event['extra_attributes']: eventinfo['singles'] = {} for single in event['extra_attributes']['SingleInspiral']: eventinfo['singles'][single['ifo']] = single eventinfo['singles'][single['ifo']]['gpstime'] = single[ 'end_time'] + 10**-9 * single['end_time_ns'] if ("H1" in eventinfo['singles']) and ("L1" in eventinfo['singles']): eventinfo["H1_L1_difference"] = eventinfo['singles']['H1'][ "gpstime"] - eventinfo['singles']['L1']["gpstime"] t = Time([ eventinfo['singles']['H1']["gpstime"], eventinfo['singles']['L1']["gpstime"] ], format='gps', scale='utc') mjds = t.mjd timediff = eventinfo["H1_L1_difference"] if 'MultiBurst' in event['extra_attributes']: eventinfo['burst'] = event['extra_attributes']['MultiBurst'] single_ifo_times = eventinfo['burst']['single_ifo_times'].split(",") ifos = eventinfo['burst']['ifos'].split(",") if len(ifos) > 1 and len(single_ifo_times) > 1: ifo1 = ifos[0] gps1 = float(single_ifo_times[0]) ifo2 = ifos[1] gps2 = float(single_ifo_times[1]) eventinfo['burst'][ifo1] = {} eventinfo['burst'][ifo1]['gpstime'] = gps1 eventinfo['burst'][ifo2] = {} eventinfo['burst'][ifo2]['gpstime'] = gps2 if ("H1" in eventinfo['burst']) and ("L1" in eventinfo['burst']): eventinfo["H1_L1_difference"] = eventinfo['burst']['H1'][ "gpstime"] - eventinfo['burst']['L1']["gpstime"] t = Time([ eventinfo['burst']['H1']["gpstime"], eventinfo['burst']['L1']["gpstime"] ], format='gps', scale='utc') mjds = t.mjd timediff = eventinfo["H1_L1_difference"] try: print "Looking for EM bright file..." r = g.files(eventinfo['graceid'], "Source_Classification_%s.json" % eventinfo['graceid']) emfile = open('embright.json', 'w') emfile.write(r.read()) emfile.close() with open('embright.json') as data_file: emdata = json.load(data_file) os.system('rm embright.json') embright_keys = [ "Prob remnant_mass_greater_than 0M_sun", "Prob EMbright" ] ns_keys = ["Prob Mass2_less_than 3M_sun", "Prob NS2"] embright_prob = -1 for key in embright_keys: if not key in embright_keys: continue embright_prob = emdata[key] break ns_prob = -1 for key in embright_keys: if not key in embright_keys: continue ns_prob = emdata[key] break eventinfo['embright'] = {} eventinfo['embright']['embright'] = embright_prob eventinfo['embright']['ns'] = ns_prob except: print "No EM bright file..." try: print "Looking for cWB file..." r = g.files(eventinfo['graceid'], "trigger_%.4f.txt" % eventinfo['gpstime']) # r = g.files(eventinfo['graceid'], "eventDump.txt") cwbfile = open('trigger.txt', 'w') cwbfile.write(r.read()) cwbfile.close() eventinfo['burst'] = {} lines = [line.rstrip('\n') for line in open('trigger.txt')] for line in lines: lineSplit = line.split(":") if len(lineSplit) < 2: continue key = lineSplit[0] value = filter(None, lineSplit[1].split(" ")) eventinfo['burst'][lineSplit[0]] = value ifo1 = eventinfo['burst']['ifo'][0] gps1 = float(eventinfo['burst']['time'][0]) ifo2 = eventinfo['burst']['ifo'][1] gps2 = float(eventinfo['burst']['time'][1]) eventinfo['burst'][ifo1] = {} eventinfo['burst'][ifo1]['gpstime'] = gps1 eventinfo['burst'][ifo2] = {} eventinfo['burst'][ifo2]['gpstime'] = gps2 if ("H1" in eventinfo['burst']) and ("L1" in eventinfo['burst']): eventinfo["H1_L1_difference"] = eventinfo['burst']['H1'][ "gpstime"] - eventinfo['burst']['L1']["gpstime"] t = Time([ eventinfo['burst']['H1']["gpstime"], eventinfo['burst']['L1']["gpstime"] ], format='gps', scale='utc') mjds = t.mjd timediff = eventinfo["H1_L1_difference"] except: print "No cWB file..." ra = 0 dec = 0 r = [] for lvfile in fileorder: #r = g.files(eventinfo['graceid'], lvfile) try: r = g.files(eventinfo['graceid'], lvfile) break except: continue if r == []: print "Download of skymaps file for %s failed..." % eventinfo['graceid'] else: skymap = open(skymapfile, 'w') skymap.write(r.read()) skymap.close() return skymapfile, eventinfo
def setup_roq(cp): """ Generates cp objects with the different ROQs applied """ use_roq = False if cp.has_option('paths', 'roq_b_matrix_directory') or cp.has_option( 'paths', 'computeroqweights'): if not cp.has_option('analysis', 'roq'): print( "Warning: If you are attempting to enable ROQ by specifying roq_b_matrix_directory or computeroqweights,\n\ please use analysis.roq in your config file in future. Enabling ROQ." ) cp.set('analysis', 'roq', True) if not cp.getboolean('analysis', 'roq'): yield cp raise StopIteration() from numpy import genfromtxt, array path = cp.get('paths', 'roq_b_matrix_directory') if not os.path.isdir(path): print("The ROQ directory %s does not seem to exist\n" % path) sys.exit(1) use_roq = True roq_paths = os.listdir(path) roq_params = {} roq_force_flow = None if cp.has_option('lalinference', 'roq_force_flow'): roq_force_flow = cp.getfloat('lalinference', 'roq_force_flow') print("WARNING: Forcing the f_low to ", str(roq_force_flow), "Hz") print( "WARNING: Overwriting user choice of flow, srate, seglen, and (mc_min, mc_max and q-min) or (mass1_min, mass1_max, mass2_min, mass2_max)" ) def key(item): # to order the ROQ bases return float(item[1]['seglen']) coinc_xml_obj = None row = None # Get file object of coinc.xml if opts.gid is not None: from ligo.gracedb.rest import GraceDb gid = opts.gid cwd = os.getcwd() if cp.has_option('analysis', 'service-url'): client = GraceDb(cp.get('analysis', 'service-url')) else: client = GraceDb() coinc_xml_obj = ligolw_utils.load_fileobj( client.files(gid, "coinc.xml"), contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler))[0] elif cp.has_option('input', 'coinc-xml'): coinc_xml_obj = ligolw_utils.load_fileobj( open(cp.get('input', 'coinc-xml'), "rb"), contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler))[0] # Get sim_inspiral from injection file if cp.has_option('input', 'injection-file'): print( "Only 0-th event in the XML table will be considered while running with ROQ\n" ) row = lsctables.SimInspiralTable.get_table( ligolw_utils.load_filename(cp.get('input', 'injection-file'), contenthandler=lsctables.use_in( ligolw.LIGOLWContentHandler)))[0] roq_bounds = pipe_utils.Query_ROQ_Bounds_Type(path, roq_paths) if roq_bounds == 'chirp_mass_q': print('ROQ has bounds in chirp mass and mass-ratio') mc_priors, trigger_mchirp = pipe_utils.get_roq_mchirp_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row) elif roq_bounds == 'component_mass': print('ROQ has bounds in component masses') # get component mass bounds, then compute the chirp mass that can be safely covered # further below we pass along the component mass bounds to the sampler, not the tighter chirp-mass, q bounds m1_priors, m2_priors, trigger_mchirp = pipe_utils.get_roq_component_mass_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row) mc_priors = {} for (roq, m1_prior), (roq2, m2_prior) in zip(m1_priors.items(), m2_priors.items()): mc_priors[roq] = sorted([ pipe_utils.mchirp_from_components(m1_prior[1], m2_prior[0]), pipe_utils.mchirp_from_components(m1_prior[0], m2_prior[1]) ]) if cp.has_option('lalinference', 'trigger_mchirp'): trigger_mchirp = float(cp.get('lalinference', 'trigger_mchirp')) roq_mass_freq_scale_factor = pipe_utils.get_roq_mass_freq_scale_factor( mc_priors, trigger_mchirp, roq_force_flow) if roq_mass_freq_scale_factor != 1.: print( 'WARNING: Rescaling ROQ basis, please ensure it is allowed with the model used.' ) # If the true chirp mass is unknown, add variations over the mass bins if opts.gid is not None or (opts.injections is not None or cp.has_option( 'input', 'injection-file')) or cp.has_option( 'lalinference', 'trigger_mchirp') or cp.has_option( 'input', 'coinc-xml'): for mc_prior in mc_priors: mc_priors[mc_prior] = array(mc_priors[mc_prior]) # find mass bin containing the trigger trigger_bin = None for roq in roq_paths: if mc_priors[roq][ 0] * roq_mass_freq_scale_factor <= trigger_mchirp <= mc_priors[ roq][1] * roq_mass_freq_scale_factor: trigger_bin = roq print('Prior in Mchirp will be [' + str(mc_priors[roq][0] * roq_mass_freq_scale_factor) + ',' + str(mc_priors[roq][1] * roq_mass_freq_scale_factor) + '] to contain the trigger Mchirp ' + str(trigger_mchirp)) break roq_paths = [trigger_bin] else: for mc_prior in mc_priors: mc_priors[mc_prior] = array( mc_priors[mc_prior]) * roq_mass_freq_scale_factor # write the master configparser cur_basedir = cp.get('paths', 'basedir') masterpath = os.path.join(cur_basedir, 'config.ini') with open(masterpath, 'w') as cpfile: cp.write(cpfile) for roq in roq_paths: this_cp = configparser.ConfigParser() this_cp.optionxform = str this_cp.read(masterpath) basedir = this_cp.get('paths', 'basedir') for dirs in 'basedir', 'daglogdir', 'webdir': val = this_cp.get('paths', dirs) newval = os.path.join(val, roq) mkdirs(newval) this_cp.set('paths', dirs, newval) this_cp.set( 'paths', 'roq_b_matrix_directory', os.path.join(cp.get('paths', 'roq_b_matrix_directory'), roq)) flow = roq_params[roq]['flow'] / roq_mass_freq_scale_factor srate = 2. * roq_params[roq]['fhigh'] / roq_mass_freq_scale_factor #if srate > 8192: # srate = 8192 seglen = roq_params[roq]['seglen'] * roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax this_cp.set('engine', 'srate', str(srate)) this_cp.set('engine', 'seglen', str(seglen)) if this_cp.has_option('lalinference', 'flow'): tmp = this_cp.get('lalinference', 'flow') tmp = eval(tmp) ifos = tmp.keys() else: tmp = {} ifos = eval(this_cp.get('analysis', 'ifos')) for i in ifos: tmp[i] = flow this_cp.set('lalinference', 'flow', str(tmp)) if roq_bounds == 'chirp_mass_q': mc_min = mc_priors[roq][0] * roq_mass_freq_scale_factor mc_max = mc_priors[roq][1] * roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax q_min = 1. / float(roq_params[roq]['qmax']) this_cp.set('engine', 'chirpmass-min', str(mc_min)) this_cp.set('engine', 'chirpmass-max', str(mc_max)) this_cp.set('engine', 'q-min', str(q_min)) this_cp.set( 'engine', 'comp-min', str( max( roq_params[roq]['compmin'] * roq_mass_freq_scale_factor, mc_min * pow(1 + q_min, 1. / 5.) * pow(q_min, 2. / 5.)))) this_cp.set( 'engine', 'comp-max', str(mc_max * pow(1 + q_min, 1. / 5.) * pow(q_min, -3. / 5.))) elif roq_bounds == 'component_mass': m1_min = m1_priors[roq][0] m1_max = m1_priors[roq][1] m2_min = m2_priors[roq][0] m2_max = m2_priors[roq][1] this_cp.set('engine', 'mass1-min', str(m1_min)) this_cp.set('engine', 'mass1-max', str(m1_max)) this_cp.set('engine', 'mass2-min', str(m2_min)) this_cp.set('engine', 'mass2-max', str(m2_max)) yield this_cp raise StopIteration()
class Events(object): """ A dictionary with all superevents from the Grace database. """ def __init__(self): self.client = GraceDb() self.data = {} self.loop = asyncio.get_event_loop() self.loop.create_task(self._periodic_event_updater()) def update_all(self): """ Get the latest events from the Grace database. Returns ------- None See Also -------- https://gracedb.ligo.org/latest/ """ events = self.client.superevents(query="-ADVNO", orderby=["-created"]) self.data = {} logging.info("Updating all events. This might take a minute.") start = time.time() for i, event in enumerate(events, 1): self._add_to_event_data(event) end = time.time() logging.info(f"Updating {i} events took {round(end - start, 2)} s.") def update_events_last_week(self): logging.info("Updating all events until 1 week ago. This might take a minute.") start = time.time() events = self.client.superevents( query="created: 1 week ago .. now -ADVNO", orderby=["-created"] ) for i, event in enumerate(events, 1): logging.info(f"Updating event {event['superevent_id']}") self._add_to_event_data(event) end = time.time() logging.info(f"Updating {i} events took {round(end - start, 2)} s.") def update_single(self, event_id: str): """ Update and store the data of a single event in the event dictionary. Parameters ---------- event_id : str Returns ------- """ # Make sure the event id has the right upper and lower case format _event_id = event_id[0].upper() + event_id[1:].lower() start = time.time() try: event = self.client.superevent(_event_id) event = event.json() except (ligo.gracedb.exceptions.HTTPError, urllib.error.HTTPError) as e: logging.error(f"Could not find event {_event_id}. Exception: {e}") return end = time.time() logging.info( f"Updating single event from database took {round(end - start, 2)} s." ) self._add_to_event_data(event) def _add_to_event_data(self, event): event_id = event.pop("superevent_id") event["created"] = dateutil.parser.parse(event["created"]) self.data[event_id] = event self._add_event_info_from_voevent(event_id) def _add_event_info_from_voevent(self, event_id: str): voevent = VOEventFromEventId() try: voevent.get(event_id) self._add_event_distance(voevent) self._add_event_classification(voevent) self._add_instruments(voevent) except (ligo.gracedb.exceptions.HTTPError, urllib.error.HTTPError) as e: logging.warning( f"Couldn't get info from VOEvent file with event id {event_id}" f"Exception: {e}" ) def _add_event_distance(self, voevent: VOEvent): """ Add distance and its standard deviation to the event dictionary. Parameters ---------- voevent : VOEvent Returns ------- None """ self.data[voevent.id]["distance_mean_Mly"] = voevent.distance self.data[voevent.id]["distance_std_Mly"] = voevent.distance_std def _add_event_classification(self, voevent: VOEvent): """ Adds the event type to the events dictionary. Possible event types are binary black hole merger, black hole neutron star merger etc. Returns ------- None """ self.data[voevent.id]["event_types"] = voevent.p_astro self.data[voevent.id]["most_likely"] = self.get_likely_event_type(voevent.id) def _add_instruments(self, voevent: VOEvent): """ Parameters ---------- voevent Returns ------- """ self.data[voevent.id]["instruments_short"] = voevent.seen_by_short self.data[voevent.id]["instruments_long"] = voevent.seen_by_long async def _periodic_event_updater(self): """ Fetches all the events from the GraceDB database. Returns ------- None """ while True: await asyncio.sleep(delay=36000) logging.info("Refreshing event database.") self.update_all() def get_likely_event_type(self, event_id: str) -> str: """ Return the most likely event type of a certain event. Parameters ---------- event_id : str The event ID you want to know the event type of. Returns ------- str Most likely event type. """ try: event_types = self.data[event_id]["event_types"] most_likely, _ = sorted( event_types.items(), key=lambda value: value[1], reverse=True )[0] except AttributeError: logging.error(f"Failed to get most likely event of {event_id}") return "" return most_likely @property def latest(self) -> Dict[str, dict]: """ Return the latest event from the Grace database. Returns ------- dict Latest event. """ for id, info in self.data.items(): return {id: info} return {"": dict()} def picture(self, event_id: str) -> str: """ Return local path of an image from a specific event. Image priority is as follows: 1) LALInference 2) skymap 3) bayestar.png. Parameters ---------- event_id : str The name of the event you want to have a picture of. Returns ------- str Local path of the image. """ files = self.client.files(event_id).json() for fname in ["LALInference", "skymap", "bayestar"]: link = get_latest_file_url(files, fname, ".png") if len(link) > 0: break if len(link) == 0: raise FileNotFoundError else: img = ImageFromUrl(link) return img.path
#------------------------------------------------- alert = sys.stdin.read() if opts.verbose: print alert alert = json.loads( alert ) graceid = alert['graceid'] if opts.verbose: print "found graceid=%s"%graceid ### figure out if this is the if (alert['alert_type']=='update') and alert['file'] and alert['file'].endswith('js') and ("_los" in alert['file']): ### this could be fragile... ### download file los = json.loads( gracedb.files( graceid, alert['file'] ).read() ) ### iterate through IFO pairs for ifo_pair, data in los.items(): mi = data['MI'] # mutual information hj = data['Hj'] # joint entropy mid = mi / hj # mutual information distance if config.has_section(ifo_pair): ### assume ifo_pair is alphabetically ordered... thr = config.getfloat(ifo_pair, 'thr') if mid > thr: labels = config.get(ifo_pair, 'labels').split() gracedb.writeLog( graceid, message='Mutual Information Distance for %s in %s line-of-sight frame is above %.3f! Applying labels: %s'%(alert['file'].split('_los')[0], ifo_pair, thr, ", ".join(labels))) for label in labels: gracedb.writeLabel( graceid, label )
eff_dist_dic = {'H1': 487.567, 'L1': 351.244} else: ifos = [ ifos['ifo'] for ifos in ev['extra_attributes']['SingleInspiral'] ] eff_dist = [ ifos['eff_distance'] if 'eff_distance' in ifos else '-' for ifos in ev['extra_attributes']['SingleInspiral'] ] eff_dist_dic = {k: v for (k, v) in zip(ifos, eff_dist)} # get BAYESTAR distance and std from .fits file if os.path.exists('fits_files/%s.fits' % args.event): pass else: files = g.files(args.event).json() fits_file = [file for file in files if file.endswith('fits')] if len(fits_file) == 0: xml_file = [ file for file in files if 'coinc' in file and file.endswith('xml') ][0] outfile = open('xml_files/%s.xml' % args.event, 'wb') r = g.files(args.event, xml_file) outfile.write(r.read()) outfile.close() file_path = 'xml_files/' + str(args.event) + '.xml' bayestar = ['bayestar-localize-coincs', file_path, file_path] subprocess.call(bayestar) file_name = 'fits_files/' + str(args.event) + '.fits' shutil.move('./0.fits', file_name) else:
#------------------------------------------------- ### download the FITS files and run snglFITS localnames = [] for graceid in opts.graceid: if opts.verbose: print('downloading FITS files associated with %s'%graceid) ### figure out which IFOs participated ifos = gracedb.event( graceid ).json()['instruments'].split(',') ### format like I like them in this repo... ifos = [ifo[0] for ifo in ifos] ### eg: H1 -> H for filename in [filename for filename in gracedb.files(graceid).json().keys() if filename.endswith('.fits') or filename.endswith('.fits.gz')]: localname = os.path.join(outdir, "%s-%s"%(graceid, filename)) if opts.verbose: print('downloading %s:%s -> %s'%(graceid, filename, localname) ) file_obj = open(localname, 'w') file_obj.write( gracedb.files( graceid, filename ).read() ) file_obj.close() localnames.append( localname ) #--------------------------------------------- ### set up snglFITShtml command snglFITScmd = [ 'snglFITShtml.py', localname, '--skip-gracedb-upload', ### REQUIRE THIS! users can upload by hand if they want
'chisq'] except KeyError: chisqi[idx] = u'none' #print("No chisq for that detector") try: eff_dist[idx] = event['extra_attributes']['SingleInspiral'][ idx]['eff_distance'] except KeyError: #print("No effective distance for that detector") key_error = "No effective distance for that detector at index" + str( idx) # print("check 4") # print(".") pipe = event['pipeline'] # f.write(gid+' '+pipe+' '+superevent+'\n') # f.write(gid+' '+pipe+'\n') fname = "%s.xml" % gid fout = open(fname, 'w+') # print("check 5") try: content = gracedb_client.files(gid, filename="coinc.xml") except: print("didn't like that gid: " + str(gid)) fout.write(content.read()) fout.close() f.write( str(gid) + ',' + str(superevent) + ',' + str(endtime) + ',' + str(chirpmass) + ',' + str(farc) + ',' + str(snrc) + ',' + str(ifos) + ',' + str(snri) + ',' + str(chisqi) + ',' + str(pipe) + ',' + str(eff_dist) + ',' + str(mass1) + ',' + str(mass2))
'alert_type' : 'update', 'uid' : graceid, ### generate an alert from graceid? Should already be a dicitonary by this point... 'object' : {'comment': 'automatic Omega Scans begun for: chanset1, chanset2.', }, } #------- OmegaScan name = 'omega scan' tests.append( (name, alert) ) #------------------------ if opts.skymaps: ### set up inputs for fitsname in [fitsname for fitsname in gdb.files( graceid ).json().keys() if fitsname.endswith('.fits') or fitsname.endswith('.fits.gz')]: alert = { 'alert_type' : 'update', 'uid' : graceid, ### generate an alert from graceid? Should already be a dicitonary by this point... 'file' : fitsname, 'object' : {'tag_names' : ['sky_loc']} } #------- SkymapSanity name = 'skymap sanity' tests.append( (name, alert) ) #------- PlotSkymap name = 'plot skymap' tests.append( (name, alert) )
def setup_roq(cp): """ Generates cp objects with the different ROQs applied """ use_roq=False if cp.has_option('paths','roq_b_matrix_directory') or cp.has_option('paths','computeroqweights'): if not cp.has_option('analysis','roq'): print("Warning: If you are attempting to enable ROQ by specifying roq_b_matrix_directory or computeroqweights,\n\ please use analysis.roq in your config file in future. Enabling ROQ.") cp.set('analysis','roq',True) if not cp.getboolean('analysis','roq'): yield cp raise StopIteration() from numpy import genfromtxt, array path=cp.get('paths','roq_b_matrix_directory') if not os.path.isdir(path): print("The ROQ directory %s does not seem to exist\n"%path) sys.exit(1) use_roq=True roq_paths=os.listdir(path) roq_params={} roq_force_flow = None if cp.has_option('lalinference','roq_force_flow'): roq_force_flow = cp.getfloat('lalinference','roq_force_flow') print("WARNING: Forcing the f_low to ", str(roq_force_flow), "Hz") print("WARNING: Overwriting user choice of flow, srate, seglen, and (mc_min, mc_max and q-min) or (mass1_min, mass1_max, mass2_min, mass2_max)") def key(item): # to order the ROQ bases return float(item[1]['seglen']) coinc_xml_obj = None row=None # Get file object of coinc.xml if opts.gid is not None: from ligo.gracedb.rest import GraceDb gid=opts.gid cwd=os.getcwd() if cp.has_option('analysis', 'service-url'): client = GraceDb(cp.get('analysis', 'service-url')) else: client = GraceDb() coinc_xml_obj = ligolw_utils.load_fileobj(client.files(gid, "coinc.xml"), contenthandler = lsctables.use_in(ligolw.LIGOLWContentHandler))[0] elif cp.has_option('input', 'coinc-xml'): coinc_xml_obj = ligolw_utils.load_fileobj(open(cp.get('input', 'coinc-xml'), "rb"), contenthandler = lsctables.use_in(ligolw.LIGOLWContentHandler))[0] # Get sim_inspiral from injection file if cp.has_option('input','injection-file'): print("Only 0-th event in the XML table will be considered while running with ROQ\n") row = lsctables.SimInspiralTable.get_table( ligolw_utils.load_filename(cp.get('input','injection-file'),contenthandler=lsctables.use_in(ligolw.LIGOLWContentHandler)) )[0] roq_bounds = pipe_utils.Query_ROQ_Bounds_Type(path, roq_paths) if roq_bounds == 'chirp_mass_q': print('ROQ has bounds in chirp mass and mass-ratio') mc_priors, trigger_mchirp = pipe_utils.get_roq_mchirp_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row ) elif roq_bounds == 'component_mass': print('ROQ has bounds in component masses') # get component mass bounds, then compute the chirp mass that can be safely covered # further below we pass along the component mass bounds to the sampler, not the tighter chirp-mass, q bounds m1_priors, m2_priors, trigger_mchirp = pipe_utils.get_roq_component_mass_priors( path, roq_paths, roq_params, key, coinc_xml_obj=coinc_xml_obj, sim_inspiral=row ) mc_priors = {} for (roq,m1_prior), (roq2,m2_prior) in zip(m1_priors.items(), m2_priors.items()): mc_priors[roq] = sorted([pipe_utils.mchirp_from_components(m1_prior[1], m2_prior[0]), pipe_utils.mchirp_from_components(m1_prior[0], m2_prior[1])]) if cp.has_option('lalinference','trigger_mchirp'): trigger_mchirp=float(cp.get('lalinference','trigger_mchirp')) roq_mass_freq_scale_factor = pipe_utils.get_roq_mass_freq_scale_factor(mc_priors, trigger_mchirp, roq_force_flow) if roq_mass_freq_scale_factor != 1.: print('WARNING: Rescaling ROQ basis, please ensure it is allowed with the model used.') # If the true chirp mass is unknown, add variations over the mass bins if opts.gid is not None or (opts.injections is not None or cp.has_option('input','injection-file')) or cp.has_option('lalinference','trigger_mchirp') or cp.has_option('input', 'coinc-xml'): for mc_prior in mc_priors: mc_priors[mc_prior] = array(mc_priors[mc_prior]) # find mass bin containing the trigger trigger_bin = None for roq in roq_paths: if mc_priors[roq][0]*roq_mass_freq_scale_factor <= trigger_mchirp <= mc_priors[roq][1]*roq_mass_freq_scale_factor: trigger_bin = roq print('Prior in Mchirp will be ['+str(mc_priors[roq][0]*roq_mass_freq_scale_factor)+','+str(mc_priors[roq][1]*roq_mass_freq_scale_factor)+'] to contain the trigger Mchirp '+str(trigger_mchirp)) break roq_paths = [trigger_bin] else: for mc_prior in mc_priors: mc_priors[mc_prior] = array(mc_priors[mc_prior])*roq_mass_freq_scale_factor # write the master configparser cur_basedir = cp.get('paths','basedir') masterpath=os.path.join(cur_basedir,'config.ini') with open(masterpath,'w') as cpfile: cp.write(cpfile) for roq in roq_paths: this_cp = configparser.ConfigParser() this_cp.optionxform = str this_cp.read(masterpath) basedir = this_cp.get('paths','basedir') for dirs in 'basedir','daglogdir','webdir': val = this_cp.get('paths',dirs) newval = os.path.join(val,roq) mkdirs(newval) this_cp.set('paths',dirs,newval) this_cp.set('paths','roq_b_matrix_directory',os.path.join(cp.get('paths','roq_b_matrix_directory'),roq)) flow=roq_params[roq]['flow'] / roq_mass_freq_scale_factor srate=2.*roq_params[roq]['fhigh'] / roq_mass_freq_scale_factor #if srate > 8192: # srate = 8192 seglen=roq_params[roq]['seglen'] * roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax this_cp.set('engine','srate',str(srate)) this_cp.set('engine','seglen',str(seglen)) if this_cp.has_option('lalinference','flow'): tmp=this_cp.get('lalinference','flow') tmp=eval(tmp) ifos=tmp.keys() else: tmp={} ifos=eval(this_cp.get('analysis','ifos')) for i in ifos: tmp[i]=flow this_cp.set('lalinference','flow',str(tmp)) if roq_bounds == 'chirp_mass_q': mc_min=mc_priors[roq][0]*roq_mass_freq_scale_factor mc_max=mc_priors[roq][1]*roq_mass_freq_scale_factor # params.dat uses the convention q>1 so our q_min is the inverse of their qmax q_min=1./float(roq_params[roq]['qmax']) this_cp.set('engine','chirpmass-min',str(mc_min)) this_cp.set('engine','chirpmass-max',str(mc_max)) this_cp.set('engine','q-min',str(q_min)) this_cp.set('engine','comp-min', str(max(roq_params[roq]['compmin'] * roq_mass_freq_scale_factor, mc_min * pow(1+q_min, 1./5.) * pow(q_min, 2./5.)))) this_cp.set('engine','comp-max', str(mc_max * pow(1+q_min, 1./5.) * pow(q_min, -3./5.))) elif roq_bounds == 'component_mass': m1_min = m1_priors[roq][0] m1_max = m1_priors[roq][1] m2_min = m2_priors[roq][0] m2_max = m2_priors[roq][1] this_cp.set('engine','mass1-min',str(m1_min)) this_cp.set('engine','mass1-max',str(m1_max)) this_cp.set('engine','mass2-min',str(m2_min)) this_cp.set('engine','mass2-max',str(m2_max)) yield this_cp raise StopIteration()
areas = config.get('stats', 'area').split() #------------------------------------------------- ### figure out which IFOs participated ifos = gracedb.event(graceid).json()['instruments'].split(',') ### format like I like them in this repo... ifos = [ifo[0] for ifo in ifos] ### eg: H1 -> H #------------------------------------------------- ### figure out which fits files we're analyzing if opts.graceid: ### download all of them filenames = sorted([ filename for filename in gracedb.files(graceid).json().keys() if filename.endswith('.fits.gz') or filename.endswith('.fits') ]) elif opts.graceid_and_filename: ### just this one filenames = [opts.graceid_and_filename[1]] else: ### read from stdin filenames = [alert['file']] ### pull out the filename ### search for other FITS files in outdir localnames = sorted( glob.glob('%s/*.fits' % outdir) + glob.glob('%s/*.fits.gz' % outdir)) if opts.Verbose: print "processing %d new FITS files" % len(filenames)