Example #1
0
    def test_initial_case(self):
        with open(datapaths.swift_bat_grb_pos_v2) as f:
            swift_alert = BatGrb(vp.load(f))
        current_utc_time = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
        request_status = {
            'sent_time': current_utc_time,
            'acknowledged': False,
        }

        v = vo_subs.create_ami_followup_notification(
            swift_alert, stream_id=1, request_status=request_status)
        vp.assert_valid_as_v2_0(v)
        with open('/tmp/test_voevent.xml', 'wb') as f:
            vp.dump(v, f)
Example #2
0
def test_voevent_generation():
    tmpdir = '/tmp/fps_feed_test/gaia'
    if not os.path.isdir(tmpdir):
        os.makedirs(tmpdir)
    feed = gaia.GaiaFeed()
    feed._content = gaia_content
    # for feed_id in feed.event_id_data_map.keys()[:10]:
    for feed_id in feed.event_id_data_map.keys():
        v = feed.generate_voevent(feed_id)
        stream_id = feed.feed_id_to_stream_id(feed_id)
        vp.assert_valid_as_v2_0(v)
        outpath = os.path.join(tmpdir, '{}.xml'.format(stream_id))
        with open(outpath, 'wb') as f:
            vp.dump(v, f)
Example #3
0
def test_assasn_voevent_generation():
    tmpdir = '/tmp/fps_feed_test/assasn'
    if not os.path.isdir(tmpdir):
        os.makedirs(tmpdir)
    feed2 = asassn.AsassnFeed()
    feed2._content = asassn_content_2018
    for feed_id in list(feed2.event_id_data_map.keys())[:10]:
        # for feed_id in feed2.id_row_map.keys():
        v = feed2.generate_voevent(feed_id)
        stream_id = feed2.feed_id_to_stream_id(feed_id)
        vp.assert_valid_as_v2_0(v)
        outpath = os.path.join(tmpdir, '{}.xml'.format(stream_id))
        with open(outpath, 'wb') as f:
            vp.dump(v, f)
Example #4
0
    def test_initial_case(self):
        with open(datapaths.swift_bat_grb_pos_v2) as f:
            swift_alert = BatGrb(vp.load(f))

        request_status = {'sent_time':datetime.datetime.utcnow(),
                          'acknowledged':False,
                          }

        v = vo_subs.create_ami_followup_notification(swift_alert,
                                                 stream_id=001,
                                                 request_status=request_status)
        vp.assert_valid_as_v2_0(v)
        with open('/tmp/test_voevent.xml', 'w') as f:
            vp.dump(v, f)
    def test_get_toplevel_params(self):
        v = self.blank
        p_foo1 = vp.Param(name='foo',
                          value=42,
                          unit='bars',
                          ac=True
                          )
        p_foo2 = vp.Param(name='foo',
                          value=123,
                          unit='bars',
                          ac=True
                          )
        p_noname = vp.Param(name='delete_me', value=111)
        param_list = [p_foo1, p_foo2, p_noname]
        del p_noname.attrib['name']
        v.What.extend(param_list)

        # Show flaws in old routine:
        with pytest.warns(FutureWarning):
            old_style_toplevel_param_dict = vp.pull_params(v)[None]
            # print(old_style_toplevel_param_dict)
            vp.assert_valid_as_v2_0(v)
            # The old 'pull_params' routine will simply drop Params with duplicate
            # names:
            assert len(old_style_toplevel_param_dict)==(len(param_list) - 1)
            none_group = vp.Group([],name=None)
            complex_group1 =vp.Group([vp.Param(name='real', value=1.),
                                    vp.Param(name='imag', value=0.5)],
                                   name='complex')
            complex_group2 =vp.Group([vp.Param(name='real', value=1.5),
                                    vp.Param(name='imag', value=2.5)],
                                   name='complex')
            group_list = [none_group, complex_group1, complex_group2]
            v.What.extend(group_list)
            vp.assert_valid_as_v2_0(v)
            old_style_toplevel_param_dict_w_group = vp.pull_params(v)[None]
            # An un-named group will also overshadow top-level Params.
            # This is a total fail, even though it's actually in-spec.
            assert len(old_style_toplevel_param_dict_w_group)==0

        toplevel_params = vp.get_toplevel_params(v)
        # .values method behaves like regular dict, one value for each key:
        assert len(toplevel_params.values())==(len(param_list) - 1)
        # Use .allvalues if you want to see duplicates:
        assert len(toplevel_params.allvalues())==len(param_list)

        grouped_params = vp.get_grouped_params(v)
        assert len(grouped_params.values())==len(group_list) - 1
        assert len(grouped_params.allvalues())==len(group_list)
Example #6
0
    def parse_VOEvent(self, voevent, mapping):
        '''
        Parse VOEvent xml file.

        :param voevent: VOEvent xml file
        :param mapping: mapping from mapping.json
        :type voevent: lxml.objectify.ObjectifiedElement, str
        :type mapping: dict
        :returns:  mapping (mapping from mapping.json with values filled),
            event_type (event_type and citation if applicable)
        :rtype: dict, tuple
        '''
        # load VOEvent xml file
        try:
            v = vp.load(voevent)
        except AttributeError:
            f = open(voevent, "rb")
            v = vp.load(f)
            f.close()
        # assert if xml file is a valid VOEvent
        vp.assert_valid_as_v2_0(v)
        # Check if the event is a new VOEvent
        # For a new VOEvent there should be no citations
        try:
            event_type = (v.xpath('Citations')[0].EventIVORN.attrib['cite'],
                          v.xpath('Citations')[0].EventIVORN.text)
        except IndexError:
            event_type = ('new', None)
        self.logger.info("Event of of type: {}".format(event_type))
        # use the mapping to get required data from VOEvent xml
        # if a path is not found in the xml it gets an empty list which is
        # removed in the next step
        # puts all params into dict param_data[group][param_name]
        try:
            param_data = vp.get_grouped_params(v)
        except AttributeError:
            # <What> section is not needed for retractions
            param_data = None
        for table in mapping.keys():  # iterate over all tables
            for idx, item in enumerate(mapping[table]):
                # Add values from XML to dictionary
                mapping[table][idx]['value'] = self.get_value(
                    v, param_data, item, event_type)
                if item.get('description'):
                    note = self.get_description(v, item)
                    if note:
                        mapping[table][idx]['note'] = note
        return mapping, event_type
Example #7
0
 def test_followup_citation(self):
     ref = 'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729'
     vp.add_citations(
         self.v,
         vp.EventIvorn('ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729',
                       cite_type=vp.definitions.cite_types.followup))
     vp.assert_valid_as_v2_0(self.v)
     self.assertEqual(len(self.v.Citations.getchildren()), 1)
     # print
     # print vp.prettystr(self.v.Citations)
     vp.add_citations(
         self.v,
         vp.EventIvorn('ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-730',
                       cite_type=vp.definitions.cite_types.followup))
     self.assertTrue(vp.valid_as_v2_0(self.v))
     #         print voe.prettystr(self.v.Citations)
     self.assertEqual(len(self.v.Citations.getchildren()), 2)
    def test_get_toplevel_params(self):
        v = self.blank
        p_foo1 = vp.Param(name='foo', value=42, unit='bars', ac=True)
        p_foo2 = vp.Param(name='foo', value=123, unit='bars', ac=True)
        p_noname = vp.Param(name='delete_me', value=111)
        param_list = [p_foo1, p_foo2, p_noname]
        del p_noname.attrib['name']
        v.What.extend(param_list)

        # Show flaws in old routine:
        with pytest.warns(FutureWarning):
            old_style_toplevel_param_dict = vp.pull_params(v)[None]
            # print(old_style_toplevel_param_dict)
            vp.assert_valid_as_v2_0(v)
            # The old 'pull_params' routine will simply drop Params with duplicate
            # names:
            assert len(old_style_toplevel_param_dict) == (len(param_list) - 1)
            none_group = vp.Group([], name=None)
            complex_group1 = vp.Group([
                vp.Param(name='real', value=1.),
                vp.Param(name='imag', value=0.5)
            ],
                                      name='complex')
            complex_group2 = vp.Group([
                vp.Param(name='real', value=1.5),
                vp.Param(name='imag', value=2.5)
            ],
                                      name='complex')
            group_list = [none_group, complex_group1, complex_group2]
            v.What.extend(group_list)
            vp.assert_valid_as_v2_0(v)
            old_style_toplevel_param_dict_w_group = vp.pull_params(v)[None]
            # An un-named group will also overshadow top-level Params.
            # This is a total fail, even though it's actually in-spec.
            assert len(old_style_toplevel_param_dict_w_group) == 0

        toplevel_params = vp.get_toplevel_params(v)
        # .values method behaves like regular dict, one value for each key:
        assert len(toplevel_params.values()) == (len(param_list) - 1)
        # Use .allvalues if you want to see duplicates:
        assert len(toplevel_params.allvalues()) == len(param_list)

        grouped_params = vp.get_grouped_params(v)
        assert len(grouped_params.values()) == len(group_list) - 1
        assert len(grouped_params.allvalues()) == len(group_list)
Example #9
0
def parse_from_voevent(voevent):
    feed = SwiftFeed(voevent)
    events = feed.parse_content_to_event_data_list()
    assert len(events) == 1
    feed_id = list(feed.event_id_data_map.keys())[0]
    voevent = feed.generate_voevent(feed_id)
    vp.assert_valid_as_v2_0(voevent)
    if True:
        # Write to file for desk-checking:
        tmpdir = '/tmp/fps_feed_test/swift'
        if not os.path.isdir(tmpdir):
            os.makedirs(tmpdir)
        outpath = os.path.join(tmpdir, '{}.xml'.format(feed_id))

        with open(outpath, 'wb') as f:
            vp.dump(voevent, f)
            print(("Example voevent output to " + outpath))
    return voevent
Example #10
0
 def test_followup_citation(self):
     ref = 'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729'
     vp.add_citations(self.v,
                      vp.EventIvorn(
                          'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729',
                          cite_type=vp.definitions.cite_types.followup)
                      )
     vp.assert_valid_as_v2_0(self.v)
     self.assertEqual(len(self.v.Citations.getchildren()), 1)
     # print
     # print vp.prettystr(self.v.Citations)
     vp.add_citations(self.v,
                      vp.EventIvorn(
                          'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-730',
                          cite_type=vp.definitions.cite_types.followup)
                      )
     self.assertTrue(vp.valid_as_v2_0(self.v))
     #         print voe.prettystr(self.v.Citations)
     self.assertEqual(len(self.v.Citations.getchildren()), 2)
Example #11
0
    def test_namespace_variations(self):
        # NB, not enclosing root element in a namespace is invalid under schema
        # But this has been seen in the past (isolated bug case?)
        # Anyway, handled easily enough
        with open(datapaths.no_namespace_test_packet, 'rb') as f:
            vff = vp.load(f)
        self.assertFalse(vp.valid_as_v2_0(vff))
        self.assertEqual(vff.tag, 'VOEvent')
        self.assertEqual(vff.attrib['ivorn'],
                         'ivo://com.dc3/dc3.broker#BrokerTest-2014-02-24T15:55:27.72')

        with open(datapaths.swift_bat_grb_pos_v2, 'rb') as f:
            xml_str = f.read()
            xml_str = xml_str.replace(b'voe', b'foobar_ns')
        # print xml_str
        vfs = vp.loads(xml_str)
        vp.assert_valid_as_v2_0(vfs)
        self.assertEqual(vfs.tag, 'VOEvent')
        self.assertEqual(vfs.attrib['ivorn'],
                         'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729')
Example #12
0
    def test_namespace_variations(self):
        # NB, not enclosing root element in a namespace is invalid under schema
        # But this has been seen in the past (isolated bug case?)
        # Anyway, handled easily enough
        with open(datapaths.no_namespace_test_packet, 'rb') as f:
            vff = vp.load(f)
        self.assertFalse(vp.valid_as_v2_0(vff))
        self.assertEqual(vff.tag, 'VOEvent')
        self.assertEqual(vff.attrib['ivorn'],
                         'ivo://com.dc3/dc3.broker#BrokerTest-2014-02-24T15:55:27.72')

        with open(datapaths.swift_bat_grb_pos_v2, 'rb') as f:
            xml_str = f.read()
            xml_str = xml_str.replace(b'voe', b'foobar_ns')
        # print xml_str
        vfs = vp.loads(xml_str)
        vp.assert_valid_as_v2_0(vfs)
        self.assertEqual(vfs.tag, 'VOEvent')
        self.assertEqual(vfs.attrib['ivorn'],
                         'ivo://nasa.gsfc.gcn/SWIFT#BAT_GRB_Pos_532871-729')
print("\n***And your What:***\n")
print(vp.prettystr(v.What))

# You would normally describe or reference your telescope / instrument here:
vp.add_how(v, descriptions='Discovered via 4PiSky',
           references=vp.Reference('http://4pisky.org'))

# The 'Why' section is optional, allows for speculation on probable
# astrophysical cause
vp.add_why(v, importance=0.5,
           inferences=vp.Inference(probability=0.1,
                                   relation='identified',
                                   name='GRB121212A',
                                   concept='process.variation.burst;em.radio')
           )

# We can also cite earlier VOEvents:
vp.add_citations(v,
                 vp.EventIvorn(
                     ivorn='ivo://astronomy.physics.science.org/super_exciting_events#101',
                     cite_type=vp.definitions.cite_types.followup))

# Check everything is schema compliant:
vp.assert_valid_as_v2_0(v)

output_filename = 'new_voevent_example.xml'
with open(output_filename, 'wb') as f:
    vp.dump(v, f)

print("Wrote your voevent to ", os.path.abspath(output_filename))
Example #14
0
def create_voevent(jsonfile=None, deployment=False, **kwargs):
    """ template syntax for voeventparse creation of voevent
    """

    required = [
        'internalname', 'mjds', 'dm', 'width', 'snr', 'ra', 'dec', 'radecerr'
    ]
    preferred = ['fluence', 'p_flux', 'importance', 'dmerr']

    # set values
    dd = kwargs.copy()
    if jsonfile is not None:  # as made by caltechdata.set_metadata
        for k, v in trigger.items():
            if k in required + preferred:
                dd[k] = v

    assert all([
        k in dd for k in required
    ]), f'Input keys {list(dd.keys())} not complete (requires {required})'

    # TODO: set this correctly
    dt = time.Time(dd['mjds'], format='mjd').to_datetime(timezone=pytz.utc)

    # create voevent instance
    role = vp.definitions.roles.observation if deployment else vp.definitions.roles.test
    v = vp.Voevent(
        stream='',  # TODO: check
        stream_id=1,
        role=role)

    vp.set_who(v,
               date=datetime.datetime.utcnow(),
               author_ivorn="voevent.dsa-110.caltech.org")  # TODO: check

    vp.set_author(v,
                  title="DSA-110 Testing Node",
                  contactName="Casey Law",
                  contactEmail="*****@*****.**")

    params = []
    dm = vp.Param(name="dm",
                  value=str(dd['dm']),
                  unit="pc/cm^3",
                  ucd="phys.dispMeasure;em.radio.750-1500MHz",
                  dataType='float',
                  ac=True)
    dm.Description = 'Dispersion Measure'
    params.append(dm)

    width = vp.Param(name="width",
                     value=str(dd['width']),
                     unit="ms",
                     ucd="time.duration;src.var.pulse",
                     dataType='float',
                     ac=True)
    width.Description = 'Temporal width of burst'
    params.append(width)

    snr = vp.Param(name="snr",
                   value=str(dd['snr']),
                   ucd="stat.snr",
                   dataType='float',
                   ac=True)
    snr.Description = 'Signal to noise ratio'
    params.append(snr)

    if 'fluence' in dd:
        fluence = vp.Param(
            name='fluence',
            value=str(dd['fluence']),
            unit='Jansky ms',
            ucd='em.radio.750-1500MHz',  # TODO: check
            dataType='float',
            ac=False)
        fluence.Description = 'Fluence'
        params.append(fluence)

    if 'p_flux' in dd:
        p_flux = vp.Param(name='peak_flux',
                          value=str(dd['p_flux']),
                          unit='Janskys',
                          ucd='em.radio.750-1500MHz',
                          dataType='float',
                          ac=True)
        p_flux.Description = 'Peak Flux'
        params.append(p_flux)

    if 'dmerr' in dd:
        dmerr = vp.Param(name="dm_error",
                         value=str(dd['dmerr']),
                         unit="pc/cm^3",
                         ucd="phys.dispMeasure;em.radio.750-1500MHz",
                         dataType='float',
                         ac=True)
        dmerr.Description = 'Dispersion Measure error'
        params.append(dmerr)

    v.What.append(vp.Group(params=params, name='event parameters'))

    vp.add_where_when(v,
                      coords=vp.Position2D(
                          ra=str(dd['ra']),
                          dec=str(dd['dec']),
                          err=str(dd['radecerr']),
                          units='deg',
                          system=vp.definitions.sky_coord_system.utc_fk5_geo),
                      obs_time=dt,
                      observatory_location='OVRO')

    print("\n***Here is your WhereWhen:***\n")
    print(vp.prettystr(v.WhereWhen))

    print("\n***And your What:***\n")
    print(vp.prettystr(v.What))

    vp.add_how(v,
               descriptions='Discovered with DSA-110',
               references=vp.Reference('http://deepsynoptic.org'))

    if 'importance' in dd:
        vp.add_why(v, importance=str(dd['importance']))
    else:
        vp.add_why(v)
    v.Why.Name = str(dd['internalname'])

    vp.assert_valid_as_v2_0(v)

    return v
Example #15
0
 def test_invalid_error_reporting(self):
     with self.assertRaises(etree.DocumentInvalid):
         v = vp.Voevent(stream='voevent.soton.ac.uk/TEST',
                        stream_id='001',
                        role='DeadParrot')
         vp.assert_valid_as_v2_0(v)
Example #16
0
 def test_invalid_error_reporting(self):
     with self.assertRaises(etree.DocumentInvalid):
         v = vp.Voevent(stream='voevent.soton.ac.uk/TEST',
                        stream_id='001',
                        role='DeadParrot')
         vp.assert_valid_as_v2_0(v)
Example #17
0
def create_grb_voevent(grb_dic, conf_vo, what_com, atable):
    """
	Create VO event with observation plan for a given telescope in the network

	:param gw_dic: dictionary with GRB infos
	:param conf_vo: dictionary to be used to fill header of VO event
	:param what_com: dictionary with common infos needed for VO creation
	:param atable: astropy table with observation plan and meta data
	:return: voevent object
	"""

    # get telescope name and role, will be used several time
    tel_name = what_com['tel_name']
    obs_mode = what_com['obs_mode']
    voevent = basic_grb_voevent(grb_dic, conf_vo, what_com)

    #GBM ground or final position
    if grb_dic["Packet_Type"] == 112 or grb_dic["Packet_Type"] == 115:
        pixloc = vp.Param(name="Loc_url",
                          value=str(grb_dic["skymap"]["localization_name"]),
                          ucd="meta.ref.url",
                          dataType="string")
        pixloc.Description = "URL to retrieve location of the healpix skymap"
        voevent.What.append(pixloc)
        if tel_name != "":
            name_tel = vp.Param(name="Name_tel",
                                value=str(tel_name),
                                ucd="instr",
                                dataType="string")
            name_tel.Description = "Name of the telescope used for the observation strategy"
            voevent.What.append(name_tel)
            if atable and atable[0]:

                # now prepare observation plan or galaxies list
                fields = objectify.Element("Table", name="Obs_plan")
                fields.Description = "Tiles for the observation plan"

                # first field is the identificaiton of the field
                # it will be different between tiling and galaxy targetting
                if obs_mode == "Tiling":
                    field_id = objectify.SubElement(fields,
                                                    "Field",
                                                    name="Field_id",
                                                    ucd="",
                                                    unit="",
                                                    dataType="string")
                    field_id.Description = "ID of the field of FOV"
                    tel_obsplan = np.transpose(
                        np.array([
                            atable['rank_id'], atable['RA'], atable['DEC'],
                            atable['Prob']
                        ]))
                else:
                    field_id = objectify.SubElement(fields,
                                                    "Field",
                                                    name="Gal_id",
                                                    ucd="",
                                                    unit="",
                                                    dataType="string")
                    field_id.Description = "ID of the galaxy"

                    # For galaxie we will uniformize how we name them based on catalogs
                    gal_id = utils_too.uniformize_galnames(atable)
                    tel_obsplan = np.transpose(
                        np.array([
                            gal_id, atable['RAJ2000'], atable['DEJ2000'],
                            atable['S']
                        ]))

                    # right_asc = objectify.SubElement(fields, "Field", name="RA", ucd="pos.eq.ra ", unit="deg", dataType="float")

                right_asc = objectify.SubElement(fields,
                                                 "Field",
                                                 name="RA",
                                                 ucd="pos.eq.ra ",
                                                 unit="deg",
                                                 dataType="float")
                right_asc.Description = "The right ascension at center of fov in equatorial coordinates"
                dec = objectify.SubElement(fields,
                                           "Field",
                                           name="Dec",
                                           ucd="pos.eq.ra ",
                                           unit="deg",
                                           dataType="float")
                dec.Description = "The declination at center of fov in equatorial coordinates"
                os_grade = objectify.SubElement(fields,
                                                "Field",
                                                name="Os_score",
                                                ucd="meta.number",
                                                unit="None",
                                                dataType="float")
                os_grade.Description = "Gives the importance of the tile/galaxy to observe"
                data = objectify.SubElement(fields, "Data")

                # loop on the observation plan
                # put a limit to 500 fields otherwise get an error when sending a VO event

                for i in np.arange(min(500, len(tel_obsplan))):
                    table_row = objectify.SubElement(data, "TR")
                    for j in np.arange(len(tel_obsplan[i])):
                        # objectify.SubElement(TR, "TD",value=str(Tel_dic["OS"][i][j]))
                        objectify.SubElement(table_row, 'TD')
                        table_row.TD[-1] = str(tel_obsplan[i][j])

                voevent.What.append(fields)
    grb_dic["dateobs"] = grb_dic["dateobs"].replace(tzinfo=pytz.utc)
    vp.add_where_when(voevent,
                      coords=vp.Position2D(
                          ra=grb_dic["ra"],
                          dec=grb_dic["dec"],
                          err=grb_dic["error"],
                          units='deg',
                          system=vp.definitions.sky_coord_system.utc_fk5_geo),
                      obs_time=grb_dic["dateobs"],
                      observatory_location=grb_dic["inst"])

    # Check everything is schema compliant:
    vp.assert_valid_as_v2_0(voevent)

    return voevent
    v.What.foo[-1] = "foo{}".format(i)
print("I have {} foos for you:".format(len(v.What.foo)))
print(vp.prettystr(v.What))

# In[ ]:

# Get rid of all the foo:
del v.What.foo[:]

# Alternatively, you can create elements independently, then append them to a parent (remember how lxml.objectify pretends elements are lists?) - this is occasionally useful if you want to write a function that returns an element, e.g. to create a new [Param](http://voevent-parse.readthedocs.org/en/master/reference.html#voeventparse.misc.Param) (but voevent-parse wraps that up for you already):

# In[ ]:

temp = objectify.Element('NonSchemaCompliantParam',
                         attrib={'somekey': 'somevalue'})
v.What.append(temp)
print(vp.prettystr(v.What))

# Obviously, these are non-schema compliant elements.
# Don't make up your own format - use Params for storing general data:

# In[ ]:

vp.valid_as_v2_0(v)

# Note that you can get a traceback if you need to figure out why a VOEvent is non-schema-compliant - this will report the first invalid element it comes across:

# In[ ]:

vp.assert_valid_as_v2_0(v)