Example #1
0
    def test_low_dec(self):
        with open(datapaths.swift_bat_grb_pos_v2) as f:
            good_src = voeventparse.load(f)
        with open(datapaths.swift_bat_grb_low_dec) as f:
            bad_src = voeventparse.load(f)

        good_fk5 = convert_voe_coords_to_eqposn(
                                     voeventparse.get_event_position(good_src))
        bad_fk5 = convert_voe_coords_to_eqposn(
                                     voeventparse.get_event_position(bad_src))
        self.assertIsNone(filters.ami.reject(good_fk5))
        self.assertIsNotNone(filters.ami.reject(bad_fk5))
Example #2
0
def handle_grb(v):
    ivorn = v.attrib['ivorn']
    TrigID = v.find(".//Param[@name='TrigID']").attrib['value']
    web_link = 'https://gcn.gsfc.nasa.gov/other/' + TrigID + '.swift'
    grb_length = is_short(v)  # Work out if it is short or long:
    if grb_length == 'short':
        coords = voeventparse.pull_astro_coords(v)
        c = voeventparse.get_event_position(v)
        if c.dec > 15.0:
            send_telegram("GRB above declination cutoff of +15 degrees  " +
                          web_link)
            #send_mail("GRB above declination cutoff of +15 degrees  "+web_link, "Short GRB above Dec cutoff")
        else:
            os.system('python schedule_atca.py ' + str(c.ra) + ' ' +
                      str(c.dec) + ' ' + web_link + ' ' + 'SHORT_GRB')
            n = Notifier()
            n.send_notification(title="SWIFT Short GRB >> TRIGGERING!",
                                text="Coords are {}".format(coords))
            send_telegram("SHORT GRB TRIGGERING  " + web_link)
    if grb_length == 'mid':
        coords = voeventparse.pull_astro_coords(v)
        c = voeventparse.get_event_position(v)
        if c.dec > 15.0:
            send_telegram("GRB above declination cutoff of +15 degrees  " +
                          web_link)
            #send_mail("GRB above declination cutoff of +15 degrees  "+web_link, "Mid GRB above Dec cutoff")
        else:
            n = Notifier()
            n.send_notification(title="SWIFT Mid GRB >> ON HOLD!",
                                text="Coords are {}".format(coords))
            #mid_grb_email('Please check:'+web_link, "Mid duration GRB", str(c.ra), str(c.dec))
            send_telegram('Please check:' + web_link +
                          " Mid duration GRB RA=" + str(c.ra) + ' DEC=' +
                          str(c.dec))
            # Send out SMS
            #send_SMS(c.ra, c.dec, web_link, subject='Mid GRB')
    if grb_length == 'long':
        #send_mail("Long GRB not triggering "+web_link, "Long GRB")
        send_telegram("Long GRB not triggering " + web_link)
    if grb_length == 'mag':
        coords = voeventparse.pull_astro_coords(v)
        c = voeventparse.get_event_position(v)
        if c.dec > 15.0:
            send_telegram(
                "GRB / Magnetar above declination cutoff of +15 degrees  " +
                web_link)
        else:
            n = Notifier()
            n.send_notification(title="SWIFT / Magnetar >> ON HOLD!",
                                text="Coords are {}".format(coords))
            send_telegram('Please check:' + web_link + " Magnetar RA=" +
                          str(c.ra) + ' DEC=' + str(c.dec))
Example #3
0
def handle_flare_star(v):
    n = Notifier()
    ivorn = v.attrib['ivorn']
    name_not_used, tel = get_name(v)
    name = get_flare_name(v)
    if tel == "SWIFT":
        TrigID = v.find(".//Param[@name='TrigID']").attrib['value']
        web_link = 'https://gcn.gsfc.nasa.gov/other/' + TrigID + '.swift'
    if tel == "MAXI":
        TrigID = v.find(".//Param[@name='TrigID']").attrib['value']
        web_link = 'https://gcn.gsfc.nasa.gov/other/8' + TrigID + '.maxi'
        #web_link = 'http://gcn.gsfc.nasa.gov/maxi.html'
    coords = voeventparse.pull_astro_coords(v)
    c = voeventparse.get_event_position(v)
    sub = vp.prettystr(v.What.Description)
    if "The sub-sub-threshold Swift-BAT trigger position notice" in sub:
        #send_mail("Flare Star "+name+" sub-sub threshold trigger", "Not triggering")
        send_telegram("Flare Star " + name + " sub-sub threshold trigger",
                      "Not triggering")
        n.send_notification(title="Flare Star " + name +
                            " sub-sub threshold burst ",
                            text="Coords are {}".format(coords))
    else:
        ra = get_flare_RA(name)
        dec = get_flare_DEC(name)
        n.send_notification(title="Flare Star " + name +
                            " Detected >> TRIGGERING!",
                            text="Coords are {}".format(coords))
        os.system('python schedule_atca.py ' + str(ra) + ' ' + str(dec) + ' ' +
                  web_link + ' ' + tel)
Example #4
0
    def __init__(self, voevent,
                 alert_notification_period=None):
        self.voevent = voevent
        self.ivorn = self.voevent.attrib['ivorn']
        self.alert_notification_period = alert_notification_period
        if self.alert_notification_period is None:
            self.alert_notification_period = default_alert_notification_period

        if not GaiaAlert.packet_type_matches(voevent):
            raise ValueError(
                "Cannot instantiate GaiaAlert; packet header mismatch.")

        group_params = voeventparse.get_grouped_params(self.voevent)
        text_params_grp = group_params[GaiaFeed.text_params_groupname]
        self.text_params = OrderedDict(
            (k, d['value']) for k, d in text_params_grp.items())

        self.id = self.text_params.get('Name')
        self.inferred_name = False

        self.isotime = voeventparse.get_event_time_as_utc(self.voevent)
        self.position = convert_voe_coords_to_eqposn(
            voeventparse.get_event_position(self.voevent))

        self.url_params = {
            'GSA':'http://gsaweb.ast.cam.ac.uk/alerts/alert/'+self.id}
Example #5
0
    def __init__(self, voevent, alert_notification_period=None):
        self.voevent = voevent
        self.ivorn = self.voevent.attrib['ivorn']
        self.alert_notification_period = alert_notification_period
        if self.alert_notification_period is None:
            self.alert_notification_period = default_alert_notification_period

        if not AsassnAlert.packet_type_matches(voevent):
            raise ValueError(
                "Cannot instantiate AsassnAlert; packet header mismatch.")

        group_params = voeventparse.get_grouped_params(self.voevent)

        text_params_grp = group_params[AsassnFeed.text_params_groupname]
        self.text_params = OrderedDict(
            (k, d['value']) for k, d in text_params_grp.items())

        url_params_grp = group_params[AsassnFeed.url_params_groupname]
        self.url_params = OrderedDict(
            (k, d['value']) for k, d in url_params_grp.items())

        self.id = self.text_params.get(AsassnKeys.id_asassn)
        if self.id is None:
            self.id = self.text_params.get(AsassnKeys.id_other)
        # Assigned name according to the 'why' section of voevent packet:
        self.inferred_name = 'ASASSN @ ' + self.text_params.get(
            AsassnKeys.detection_timestamp)
        self.isotime = voeventparse.get_event_time_as_utc(self.voevent)

        self.position = convert_voe_coords_to_eqposn(
            voeventparse.get_event_position(self.voevent))
Example #6
0
 def test_get_event_position(self):
     known_swift_grb_posn = vp.Position2D(ra=74.741200, dec=-9.313700,
                                          err=0.05,
                                          units='deg',
                                          system='UTC-FK5-GEO')
     p = vp.get_event_position(self.swift_grb_v2_packet)
     self.assertEqual(p, known_swift_grb_posn)
     self.assertIsInstance(p.ra, float)
Example #7
0
    def from_etree(root):
        """
        Load up the coords, if present, for initializing with the Voevent.

        .. note::

            Current implementation is quite slack with regard to co-ordinate
            systems - it is assumed that, for purposes of searching the database
            using spatial queries, the FK5 / ICRS reference systems and and
            geocentric/barycentric reference frames are sufficiently similar
            that we can just take the RA/Dec and insert it 'as-is' into the
            database.

            This is partly justified on the assumption that anyone in
            need of ultra-high precision co-ordinates will need to take
            account of mission specific properties anyway (e.g. position
            of GAIA at time of detection) and so will only be using the
            spatial query for a coarse search, then parsing packets
            to determine precise locations.
        """

        acceptable_coord_systems = (
            vp.definitions.sky_coord_system.utc_fk5_geo,
            vp.definitions.sky_coord_system.utc_fk5_topo,
            vp.definitions.sky_coord_system.utc_icrs_geo,
            vp.definitions.sky_coord_system.utc_icrs_topo,
            vp.definitions.sky_coord_system.tdb_fk5_bary,
            vp.definitions.sky_coord_system.tdb_icrs_bary,
        )

        position_list = []
        astrocoords = root.xpath(
            'WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords')
        if astrocoords:
            for idx, entry in enumerate(astrocoords):
                posn = vp.get_event_position(root, idx)
                if posn.system not in acceptable_coord_systems:
                    raise NotImplementedError(
                        "Loading position from coord-sys "
                        "is not yet implemented: {} ".format(posn.system))
                if posn.units != vp.definitions.units.degrees:
                    raise NotImplementedError(
                        "Loading positions in formats other than degrees "
                        "is not yet implemented.")
                try:
                    isotime = vp.get_event_time_as_utc(root, idx)
                except:
                    logger.warning("Error pulling event time for ivorn {}, "
                                   "setting to NULL".format(
                                       root.attrib['ivorn']))
                    isotime = None

                position_list.append(
                    Coord(ra=posn.ra,
                          dec=posn.dec,
                          error=posn.err,
                          time=isotime))
        return position_list
 def test_get_event_position(self):
     known_swift_grb_posn = vp.Position2D(ra=74.741200,
                                          dec=-9.313700,
                                          err=0.05,
                                          units='deg',
                                          system='UTC-FK5-GEO')
     p = vp.get_event_position(self.swift_grb_v2_packet)
     self.assertEqual(p, known_swift_grb_posn)
     self.assertIsInstance(p.ra, float)
Example #9
0
    def get_coord(v, coordname):
        '''
        Get coordinate from VOEvent file.
          - transform to HH:MM:SS if coordname=ra
          - transform to DD:HH:SS if coordname=dec

        :param v: VOEvent xml
        :param coordname: coordinate name ('ra' or 'dec')
        :type v: lxml.objectify.ObjectifiedElement
        :type coordname: str
        :returns: location string in HH:MM:SS.MS for coordname=ra
            or DD:HH:SS.MS for coordname=dec
        :rtype: str
        '''
        try:
            units = getattr(vp.get_event_position(v, index=0), 'units')
        except AttributeError:
            return None
        if not (units == 'deg'):
            raise AttributeError(
                'Unable to determine units for position: {}'.format(
                    vp.get_event_position(v, index=0)))
        position = vp.get_event_position(v, index=0)
        if (position.system == 'UTC-FK5-GEO'):
            skcoord = SkyCoord(ra=position.ra * u.degree,
                               dec=position.dec * u.degree,
                               frame='fk5')
        else:
            # use default reference frame
            skcoord = SkyCoord(ra=position.ra * u.degree,
                               dec=position.dec * u.degree)
        if (coordname == 'ra'):
            # ra location is in hms
            coordloc = skcoord.ra.hms
        elif (coordname == 'dec'):
            # dec location is in dms
            coordloc = skcoord.dec.dms
        # format location tuple to string
        locstring = '{}:{}:{}'.format(
            str(int(round(coordloc[0]))).zfill(2),
            str(abs(int(round(coordloc[1])))).zfill(2),
            "{:.2f}".format(abs(coordloc[2])).zfill(5))
        return locstring
Example #10
0
 def test_spatial_query(self, fixture_db_session):
     s = fixture_db_session
     posn = vp.get_event_position(swift_bat_grb_655721)
     # Cone search centred on the known co-ords should return the row:
     results = s.query(Coord).filter(
         coord_cone_search_clause(posn.ra, posn.dec, 0.5)).all()
     assert len(results) == 1
     # Now bump the cone to the side (so not matching) and check null return
     results = s.query(Coord).filter(
         coord_cone_search_clause(posn.ra, posn.dec + 1.0, 0.5)).all()
     assert len(results) == 0
Example #11
0
    def __init__(self, payload):
        super().__init__(payload)

        # Get XML param dicts
        # NB: you can't store these on the Event because they're unpickleable.
        top_params = vp.get_toplevel_params(self.voevent)
        # group_params = vp.get_grouped_params(self.voevent)

        # Default params
        self.notice = EVENT_DICTIONARY[self.packet_type]['notice_type']
        self.type = EVENT_DICTIONARY[self.packet_type]['event_type']
        self.source = EVENT_DICTIONARY[self.packet_type]['source']

        # Get the run and event ID (e.g. 13311922683750)
        self.id = top_params['AMON_ID']['value']

        # Create our own event name (e.g. ICECUBE_13311922683750)
        self.name = '{}_{}'.format(self.source, self.id)

        # Get info from the VOEvent
        # signalness: the probability this is an astrophysical signal relative to backgrounds
        self.signalness = float(top_params['signalness']['value'])
        self.far = float(top_params['FAR']['value'])

        # Position coordinates
        self.position = vp.get_event_position(self.voevent)
        self.coord = SkyCoord(ra=self.position.ra,
                              dec=self.position.dec,
                              unit=self.position.units)
        self.target = FixedTarget(self.coord)

        # Position error
        self.coord_error = Angle(self.position.err, unit=self.position.units)

        # Systematic error for cascade event is given, so = 0
        if self.notice == 'ICECUBE_CASCADE':
            self.systematic_error = Angle(0, unit='deg')
        else:
            self.systematic_error = Angle(.2, unit='deg')
        self.total_error = Angle(np.sqrt(self.coord_error**2 +
                                         self.systematic_error**2),
                                 unit='deg')

        # Enclosed skymap url for CASCADE_EVENT, but others
        # Get skymap URL
        if 'skymap_fits' in top_params:
            self.skymap_url = top_params['skymap_fits']['value']
        else:
            self.skymap_url = None

        # Don't download the skymap here, it may well be very large.
        # Only do it when it's absolutely necessary
        # These params will only be set once the skymap is downloaded
        self.contour_areas = {0.5: None, 0.9: None}
Example #12
0
 def test_spatial_query(self, fixture_db_session):
     s = fixture_db_session
     posn = vp.get_event_position(swift_bat_grb_655721)
     # Cone search centred on the known co-ords should return the row:
     results = s.query(Coord).filter(
         coord_cone_search_clause(posn.ra, posn.dec, 0.5)).all()
     assert len(results) == 1
     # Now bump the cone to the side (so not matching) and check null return
     results = s.query(Coord).filter(
         coord_cone_search_clause(posn.ra, posn.dec + 1.0, 0.5)).all()
     assert len(results) == 0
Example #13
0
 def test_set_wherewhen(self):
     tz_aware_timestamp = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
     vp.add_where_when(self.v, coords=self.coords1,
                       obs_time=tz_aware_timestamp,
                       observatory_location=vp.definitions.observatory_location.geosurface)
     self.assertTrue(vp.valid_as_v2_0(self.v))
     self.assertEqual(self.coords1, vp.get_event_position(self.v))
     self.assertIsNotNone(vp.get_event_time_as_utc(self.v))
     astrocoords = self.v.xpath(
         'WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords'
     )[0]
     isotime_str = str(astrocoords.Time.TimeInstant.ISOTime)
     self.assertFalse('+' in isotime_str)
Example #14
0
 def test_set_wherewhen(self):
     tz_aware_timestamp = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
     vp.add_where_when(self.v, coords=self.coords1,
                       obs_time=tz_aware_timestamp,
                       observatory_location=vp.definitions.observatory_location.geosurface)
     self.assertTrue(vp.valid_as_v2_0(self.v))
     self.assertEqual(self.coords1, vp.get_event_position(self.v))
     self.assertIsNotNone(vp.get_event_time_as_utc(self.v))
     astrocoords = self.v.xpath(
         'WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords'
     )[0]
     isotime_str = str(astrocoords.Time.TimeInstant.ISOTime)
     self.assertFalse('+' in isotime_str)
Example #15
0
 def test_coords_loaded(self, fixture_db_session):
     s = fixture_db_session
     n_total_coords = s.query(Coord).count()
     assert n_total_coords == 1
     grb_packet_coords = s.query(Voevent).filter(
         Voevent.ivorn == swift_bat_grb_655721.attrib['ivorn']).one().coords
     assert len(grb_packet_coords) == 1
     coord0 = grb_packet_coords[0]
     bat_voevent_id = s.query(Voevent.id).filter(
         Voevent.ivorn == swift_bat_grb_655721.attrib['ivorn']).scalar()
     assert coord0.voevent_id == bat_voevent_id
     position = vp.get_event_position(swift_bat_grb_655721)
     assert coord0.ra == position.ra
     assert coord0.dec == position.dec
     assert coord0.error == position.err
Example #16
0
    def __init__(self, voevent):
        self.voevent = voevent
        self.ivorn = self.voevent.attrib['ivorn']
        if not BatGrb.packet_type_matches(voevent):
            raise ValueError("Cannot instantiate AsassnAlert; packet header mismatch.")

        id_long_short = self._pull_swift_bat_id()
        self.id_long = 'SWIFT_' + id_long_short[0]
        self.id = 'SWIFT_' + id_long_short[1]
        #Assigned name according to the 'why' section of voevent packet:
        self.inferred_name = self.voevent.Why.Inference.Name
        self.isotime = voeventparse.get_event_time_as_utc(self.voevent)
        self.group_params = voeventparse.get_grouped_params(self.voevent)
        self.position = convert_voe_coords_to_eqposn(
                                       voeventparse.get_event_position(self.voevent))
        self.alert_notification_period = False
Example #17
0
 def test_coords_loaded(self, fixture_db_session):
     s = fixture_db_session
     n_total_coords = s.query(Coord).count()
     assert n_total_coords == 1
     grb_packet_coords = s.query(Voevent).filter(
         Voevent.ivorn == swift_bat_grb_655721.attrib['ivorn']
     ).one().coords
     assert len(grb_packet_coords) == 1
     coord0 = grb_packet_coords[0]
     bat_voevent_id = s.query(Voevent.id).filter(
         Voevent.ivorn == swift_bat_grb_655721.attrib['ivorn']
     ).scalar()
     assert coord0.voevent_id == bat_voevent_id
     position = vp.get_event_position(swift_bat_grb_655721)
     assert coord0.ra == position.ra
     assert coord0.dec == position.dec
     assert coord0.error == position.err
Example #18
0
 def assign_test_client_and_initdb(self, flask_test_client,
                                   fixture_db_session):
     self.c = flask_test_client  # Purely for brevity
     n_packets = 17
     packets = heartbeat_packets(n_packets=n_packets)
     for counter, pkt in enumerate(packets, start=1):
         packet_dec = 180.0 / n_packets * counter - 90
         coords = vp.Position2D(
             ra=15, dec=packet_dec, err=0.1,
             units=vp.definitions.units.degrees,
             system=vp.definitions.sky_coord_system.utc_icrs_geo)
         # print "Inserting coords", coords
         vp.add_where_when(
             pkt,
             coords=coords,
             obs_time=iso8601.parse_date(pkt.Who.Date.text),
             observatory_location=vp.definitions.observatory_location.geosurface
         )
     self.packets = packets
     self.ivorn_dec_map = {}
     for pkt in self.packets:
         posn = vp.get_event_position(pkt)
         self.ivorn_dec_map[pkt.attrib['ivorn']] = posn.dec
         fixture_db_session.add(Voevent.from_etree(pkt))
Example #19
0
 def assign_test_client_and_initdb(self, flask_test_client,
                                   fixture_db_session):
     self.c = flask_test_client  # Purely for brevity
     n_packets = 17
     packets = heartbeat_packets(n_packets=n_packets)
     for counter, pkt in enumerate(packets, start=1):
         packet_dec = 180.0 / n_packets * counter -90
         coords = vp.Position2D(
                 ra=15, dec=packet_dec, err=0.1,
                 units=vp.definitions.units.degrees,
                 system=vp.definitions.sky_coord_system.utc_icrs_geo)
         # print "Inserting coords", coords
         vp.add_where_when(
                 pkt,
                 coords=coords,
                 obs_time=iso8601.parse_date(pkt.Who.Date.text),
                 observatory_location=vp.definitions.observatory_location.geosurface
         )
     self.packets = packets
     self.ivorn_dec_map = {}
     for pkt in self.packets:
         posn = vp.get_event_position(pkt)
         self.ivorn_dec_map[pkt.attrib['ivorn']] = posn.dec
         fixture_db_session.add(Voevent.from_etree(pkt))
Example #20
0
def handler():
    """ Convert VOEvent from stdin to parquet file, and store it.

    The user will have to define the following constants:
    EVENTDIR: str
    USEHDFS: bool
    HOST: str
    PORT: int
    USER: str

    They are stored in the fink_voevent/vo_writer.py file.

    Usage as a Comet handler:
        twistd -n comet --verbose --local-ivo=ivo://fink-broker/$(hostname)\
            --remote=voevent.4pisky.org --cmd=fink_voevent/vo_writer.py

    Usage as a standard script:
        cat a_voevent_from_disk | fink_voevent/vo_writer.py
    """
    # Check if the outdir exists
    if not vo.check_dir_exist(EVENTDIR, USEHDFS):
        print("EVENTDIR={} does not exist".format(EVENTDIR))
        print("Create it or edit fink_broker/vo_writer.py")
        sys.exit()

    # Read the data from the stdin (string)
    packet_data = sys.stdin.buffer.read()

    # Load as XML
    xml_packet_data = voeventparse.loads(packet_data)

    # Extract the ivorn
    ivorn = xml_packet_data.attrib['ivorn']

    # Skip if the event is a test
    if not vo.is_observation(xml_packet_data):
        print('test/utility received - {}'.format(ivorn))
        return 0

    # Extract information about position and time
    coords = voeventparse.get_event_position(xml_packet_data)
    time_utc = str(voeventparse.get_event_time_as_utc(xml_packet_data))

    # Store useful information for coincidence in a DataFrame
    df = pd.DataFrame.from_dict(
        {
            'ivorn': [ivorn],
            'ra': [coords.ra],
            'dec': [coords.dec],
            'err': [coords.err],
            'units': [coords.units],
            'timeUTC': [time_utc],
            'raw_event': packet_data}
    )

    # Filename for the event is based on the ivorn.
    fn = '{}/{}.parquet'.format(EVENTDIR, vo.string_to_filename(ivorn))

    # Get the connector
    if USEHDFS:
        fs = vo.get_hdfs_connector(HOST, PORT, USER)
    else:
        fs = None
    vo.write_dataframe(df, outpath=fn, fs=fs)

    return 0
def handle_flarestar(v, pretend=False):
    """
    Handles the actual VOEvent parsing, generating observations if appropriate.

    :param v: string in VOEvent XML format
    :param pretend: Boolean, True if we don't want to actually schedule the observations.
    :return: None
    """
    ivorn = v.attrib['ivorn']
    log.debug("processing Flare Star {0}".format(ivorn))

    name = v.Why.Inference.Name
    trig_id = v.find(".//Param[@name='TrigID']").attrib['value']
    c = voeventparse.get_event_position(v)
    if c.dec > DEC_LIMIT:
        msg = "Flare Star {0} above declination cutoff of +10 degrees".format(
            name)
        log.debug(msg)
        log.debug("Not triggering")
        handlers.send_email(
            from_address='*****@*****.**',
            to_addresses=DEBUG_NOTIFY_LIST,
            subject='GRB_fermi_swift debug notification for trigger: %s' %
            trig_id,
            msg_text=DEBUG_EMAIL_TEMPLATE % msg,
            attachments=[('voevent.xml', voeventparse.dumps(v))])
        return

    if trig_id not in xml_cache:
        fs = FlareStar(event=v)
        fs.trigger_id = trig_id
        xml_cache[trig_id] = fs
    else:
        fs = xml_cache[trig_id]
        fs.add_event(v)

    ra = c.ra
    dec = c.dec
    fs.add_pos((ra, dec, 0.))
    fs.debug("Flare Star {0} is detected at RA={1}, Dec={2}".format(
        name, ra, dec))

    req_time_min = 30

    # look at the schedule
    obslist = triggerservice.obslist(obstime=1800)
    if obslist is not None and len(obslist) > 0:
        fs.debug("Currently observing:")
        fs.debug(str(obslist))
        # are we currently observing *this* GRB?
        obs = str(
            obslist[0][1])  # in case the obslist is returning unicode strings
        fs.debug("obs {0}, trig {1}".format(obs, trig_id))

        # Same GRB trigger from same telescope
        if obs == trig_id:
            fs.info("already observing this star")
            fs.info("not triggering again")
            handlers.send_email(
                from_address='*****@*****.**',
                to_addresses=DEBUG_NOTIFY_LIST,
                subject='GRB_fermi_swift debug notification for trigger: %s' %
                trig_id,
                msg_text=DEBUG_EMAIL_TEMPLATE %
                '\n'.join([str(x) for x in fs.loglist]),
                attachments=[('voevent.xml', voeventparse.dumps(v))])
            return
    else:
        fs.debug("Current schedule empty")

    fs.debug("Triggering")
    # label as SWIFT or MAXI for the trigger type
    ttype = v.attrib['ivorn'].split('/')[-1].split('#')[0]

    emaildict = {
        'triggerid':
        fs.trigger_id,
        'trigtime':
        Time.now().iso,
        'ra':
        Angle(fs.ra[-1],
              unit=astropy.units.deg).to_string(unit=astropy.units.hour,
                                                sep=':'),
        'dec':
        Angle(fs.dec[-1],
              unit=astropy.units.deg).to_string(unit=astropy.units.deg,
                                                sep=':'),
        'name':
        name
    }
    email_text = EMAIL_TEMPLATE % emaildict
    email_subject = EMAIL_SUBJECT_TEMPLATE % fs.trigger_id
    # Do the trigger
    result = fs.trigger_observation(
        ttype=ttype,
        obsname=trig_id,
        time_min=req_time_min,
        pretend=pretend,
        project_id=PROJECT_ID,
        secure_key=SECURE_KEY,
        email_tolist=NOTIFY_LIST,
        email_text=email_text,
        email_subject=email_subject,
        creator='VOEvent_Auto_Trigger: FlareStar_swift_maxi=%s' % __version__,
        voevent=voeventparse.dumps(v))
    if result is None:
        handlers.send_email(
            from_address='*****@*****.**',
            to_addresses=DEBUG_NOTIFY_LIST,
            subject='GRB_fermi_swift debug notification for trigger: %s' %
            trig_id,
            msg_text=DEBUG_EMAIL_TEMPLATE %
            '\n'.join([str(x) for x in fs.loglist]),
            attachments=[('voevent.xml', voeventparse.dumps(v))])
Example #22
0
# Changing values:
v_copy.Who.Author.shortName = 'BillyBob'
v_copy.attrib['role'] = voeventparse.definitions.roles.test
print("Changes valid? ", voeventparse.valid_as_v2_0(v_copy))

v_copy.attrib['role'] = 'flying circus'
print("How about now? ", voeventparse.valid_as_v2_0(v_copy))
print("But the original is ok, because we copied? ",
      voeventparse.valid_as_v2_0(v))

v.Who.BadPath = "This new attribute certainly won't conform with the schema."
assert voeventparse.valid_as_v2_0(v) == False
del v.Who.BadPath
assert voeventparse.valid_as_v2_0(v) == True
#######################################################
# And now, SCIENCE
#######################################################
c = voeventparse.get_event_position(v)
print("Coords:", c)
print()
toplevel_params = voeventparse.get_toplevel_params(v)

# print("Toplevel Params:")
# pp.pprint(toplevel_params.items())
print("Trigger ID:", toplevel_params['TrigID']['value'])
grouped_params = voeventparse.get_grouped_params(v)
# pp.pprint(grouped_params.allitems())
print(
"GRB Identified:", grouped_params['Solution_Status']['GRB_Identified']['value'])
Example #23
0
    def __init__(self, payload):
        super().__init__(payload)

        # Get XML param dicts
        # NB: you can't store these on the Event because they're unpickleable.
        top_params = vp.get_toplevel_params(self.voevent)
        group_params = vp.get_grouped_params(self.voevent)

        # Default params
        self.notice = EVENT_DICTIONARY[self.packet_type]['notice_type']
        self.type = 'GRB'
        self.source = EVENT_DICTIONARY[self.packet_type]['source']

        # Get the event ID (e.g. 579943502)
        self.id = top_params['TrigID']['value']

        # Create our own event name (e.g. Fermi_579943502)
        self.name = '{}_{}'.format(self.source, self.id)

        # Get properties from the VOEvent
        if self.source == 'Fermi':
            self.properties = {
                key: group_params['Trigger_ID'][key]['value']
                for key in group_params['Trigger_ID'] if key != 'Long_short'
            }
            try:
                self.duration = group_params['Trigger_ID']['Long_short'][
                    'value']
            except KeyError:
                # Some don't have the duration
                self.duration = 'unknown'
        elif self.source == 'Swift':
            self.properties = {
                key: group_params['Solution_Status'][key]['value']
                for key in group_params['Solution_Status']
            }
        for key in self.properties:
            if self.properties[key] == 'true':
                self.properties[key] = True
            elif self.properties[key] == 'false':
                self.properties[key] = False

        # Position coordinates
        self.position = vp.get_event_position(self.voevent)
        self.coord = SkyCoord(ra=self.position.ra,
                              dec=self.position.dec,
                              unit=self.position.units)
        self.target = FixedTarget(self.coord)

        # Position error
        self.coord_error = Angle(self.position.err, unit=self.position.units)
        if self.source == 'Fermi':
            self.systematic_error = Angle(5.6, unit='deg')
        else:
            self.systematic_error = Angle(0, unit='deg')
        self.total_error = Angle(np.sqrt(self.coord_error**2 +
                                         self.systematic_error**2),
                                 unit='deg')

        # Galactic coordinates
        self.gal_lat = self.coord.galactic.b.value
        galactic_center = SkyCoord(l=0, b=0, unit='deg,deg', frame='galactic')
        self.gal_dist = self.coord.galactic.separation(galactic_center).value

        # Try creating the Fermi skymap url
        # Fermi haven't actually updated their alerts to include the URL to the HEALPix skymap,
        # but we can try and create it based on the typical location.
        try:
            old_url = top_params['LightCurve_URL']['value']
            skymap_url = old_url.replace('lc_medres34', 'healpix_all').replace(
                '.gif', '.fit')
            self.skymap_url = skymap_url
        except Exception:
            # Worth a try, fall back to creating our own
            self.skymap_url = None

        # Don't create or download the skymap here, it may well be very large.
        # Only do it when it's absolutely necessary
        # These params will only be set once the skymap is downloaded
        self.contour_areas = {0.5: None, 0.9: None}
Example #24
0
def set_dict(ve, groupid, phot_dict={}, event_dict={}):
    """ assign values to TNS dictionary. Most values taken from parsed VOEvent file.
    - groupid is associated with bot registred with TNS (used for "reporting_groupid" and "groupid").

    Optional dictionary input to overload some fields:
    - phot_dict is dictionary for "photometry" keys to set: "snr", "flux", "flux_error", "fluence", "burst_width", "sampling_time".
    - event_dict is dictionary for other TNS keys (from frb_report set): "internal_name", "reporter", "remarks", "host_name", "repeater_of_objid".
    """

    tns_dict['frb_report']['0']["internal_name"] = str(ve.Why.Name)
    tns_dict['frb_report']['0']["reporter"] = "Casey J. Law"
    pos = voeventparse.get_event_position(ve)
    tns_dict['frb_report']['0']['ra']['value'] = pos.ra
    tns_dict['frb_report']['0']['dec']['value'] = pos.dec
    tns_dict['frb_report']['0']['ra']['error'] = pos.err
    tns_dict['frb_report']['0']['dec']['error'] = pos.err
    dt = voeventparse.get_event_time_as_utc(ve)
    dtstring = f'{dt.date().isoformat()} {dt.time().isoformat()}'
    tns_dict['frb_report']['0']["discovery_datetime"] = dtstring
    tns_dict['frb_report']['0']["reporting_groupid"] = groupid
    tns_dict['frb_report']['0']["groupid"] = groupid
    tns_dict['frb_report']['0']["at_type"] = "5"  # FRBs

    params = voeventparse.get_grouped_params(ve)
    tns_dict['frb_report']['0']["dm"] = params['event parameters']['dm'][
        'value']
    try:
        tns_dict['frb_report']['0']["dmerr"] = params['event parameters'][
            'dm_error']['value']
    except KeyError:
        pass
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "snr"] = params['event parameters']['snr']['value']
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "burst_width"] = params['event parameters']['width']['value']
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "filter_value"] = 129
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "instrument_value"] = 239
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "flux"] = 0  # TODO: set this
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "flux_error"] = 0  # TODO: set this
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "limiting_flux"] = 0
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "obsdate"] = dtstring
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "flux_units"] = "Jy"
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "ref_freq"] = "1405"
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "inst_bandwidth"] = "250"
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "channels_no"] = 1024
    tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
        "sampling_time"] = 1

    # set photometry values
    for key, value in phot_dict.items():
        if key in tns_dict['frb_report']['0']["photometry"][
                "photometry_group"]["0"]:
            print(f'Overloading event key {key} with {value}')
            tns_dict['frb_report']['0']["photometry"]["photometry_group"]["0"][
                key] = value

    # overload other values
    for key, value in event_dict.items():
        if key in tns_dict['frb_report']['0']:
            print(f'Overloading event key {key} with {value}')
            tns_dict['frb_report']['0'][key] = value

    return tns_dict
Example #25
0
    def from_etree(root):
        """
        Load up the coords, if present, for initializing with the Voevent.

        .. note::

            Current implementation is quite slack with regard to co-ordinate
            systems - it is assumed that, for purposes of searching the database
            using spatial queries, the FK5 / ICRS reference systems and and
            geocentric/barycentric reference frames are sufficiently similar
            that we can just take the RA/Dec and insert it 'as-is' into the
            database.

            This is partly justified on the assumption that anyone in
            need of ultra-high precision co-ordinates will need to take
            account of mission specific properties anyway (e.g. position
            of GAIA at time of detection) and so will only be using the
            spatial query for a coarse search, then parsing packets
            to determine precise locations.
        """

        acceptable_coord_systems = (
            vp.definitions.sky_coord_system.utc_fk5_geo,
            vp.definitions.sky_coord_system.utc_fk5_topo,
            vp.definitions.sky_coord_system.utc_icrs_geo,
            vp.definitions.sky_coord_system.utc_icrs_topo,
            vp.definitions.sky_coord_system.tdb_fk5_bary,
            vp.definitions.sky_coord_system.tdb_icrs_bary,
        )

        position_list = []
        astrocoords = root.xpath(
            'WhereWhen/ObsDataLocation/ObservationLocation/AstroCoords'
        )
        if astrocoords:
            for idx, entry in enumerate(astrocoords):
                posn = vp.get_event_position(root,idx)
                if posn.system not in acceptable_coord_systems:
                    raise NotImplementedError(
                        "Loading position from coord-sys "
                        "is not yet implemented: {} ".format(
                            posn.system
                        )
                    )
                if posn.units != vp.definitions.units.degrees:
                    raise NotImplementedError(
                        "Loading positions in formats other than degrees "
                        "is not yet implemented."
                    )
                try:
                    isotime = vp.get_event_time_as_utc(root,idx)
                except:
                    logger.warning(
                        "Error pulling event time for ivorn {}, "
                        "setting to NULL".format(root.attrib['ivorn'])
                    )
                    isotime = None

                position_list.append(
                    Coord(ra = posn.ra,
                          dec = posn.dec,
                          error = posn.err,
                          time = isotime)
                )
        return position_list