예제 #1
0
    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))
예제 #3
0
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
예제 #4
0
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()
예제 #5
0
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
예제 #6
0
#-------------------------------------------------

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:
예제 #8
0
#-------------------------------------------------

### 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) )
예제 #11
0
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()
예제 #12
0
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)