def test_multiple_obs(self): tz_aware_timestamp = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC) tz_naive_timestamp = datetime.datetime.utcnow() self.assertEqual(self.v.WhereWhen.countchildren(), 0) vp.add_where_when(self.v, coords=self.coords1, obs_time=tz_aware_timestamp, observatory_location=vp.definitions.observatory_location.geosurface) self.assertEqual(self.v.WhereWhen.countchildren(), 1) vp.add_where_when(self.v, coords=self.coords2, obs_time=tz_naive_timestamp, observatory_location=vp.definitions.observatory_location.geosurface, allow_tz_naive_datetime=True, ) self.assertEqual(self.v.WhereWhen.countchildren(), 2) self.assertTrue(vp.valid_as_v2_0(self.v)) # How to reset to empty state? self.v.WhereWhen.ObsDataLocation = [] self.assertEqual(self.v.WhereWhen.countchildren(), 0) self.assertTrue(vp.valid_as_v2_0(self.v)) # print vp.prettystr(self.v.WhereWhen) # print vp.dumps(self.v) vp.add_where_when(self.v, coords=self.coords2, obs_time=tz_aware_timestamp, observatory_location=vp.definitions.observatory_location.geosurface) self.assertEqual(self.v.WhereWhen.countchildren(), 1) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_multiple_obs(self): tz_aware_timestamp = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC) tz_naive_timestamp = datetime.datetime.utcnow() self.assertEqual(self.v.WhereWhen.countchildren(), 0) vp.add_where_when(self.v, coords=self.coords1, obs_time=tz_aware_timestamp, observatory_location=vp.definitions.observatory_location.geosurface) self.assertEqual(self.v.WhereWhen.countchildren(), 1) vp.add_where_when(self.v, coords=self.coords2, obs_time=tz_naive_timestamp, observatory_location=vp.definitions.observatory_location.geosurface, allow_tz_naive_datetime=True, ) self.assertEqual(self.v.WhereWhen.countchildren(), 2) self.assertTrue(vp.valid_as_v2_0(self.v)) # How to reset to empty state? self.v.WhereWhen.ObsDataLocation = [] self.assertEqual(self.v.WhereWhen.countchildren(), 0) self.assertTrue(vp.valid_as_v2_0(self.v)) # print vp.prettystr(self.v.WhereWhen) # print vp.dumps(self.v) vp.add_where_when(self.v, coords=self.coords2, obs_time=tz_aware_timestamp, observatory_location=vp.definitions.observatory_location.geosurface) self.assertEqual(self.v.WhereWhen.countchildren(), 1) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_for_packet_mangling(self): """ Check that applying prettystr to a packet does not change it. """ self.assertTrue(vp.valid_as_v2_0(self.swift_grb_v2_packet)) before = vp.dumps(self.swift_grb_v2_packet) vp.prettystr(self.swift_grb_v2_packet) self.assertTrue(vp.valid_as_v2_0(self.swift_grb_v2_packet)) after = vp.dumps(self.swift_grb_v2_packet) self.assertEqual(before, after)
def test_for_packet_mangling(self): """ Check that applying prettystr to a packet does not change it. """ self.assertTrue(vp.valid_as_v2_0(self.swift_grb_v2_packet)) before = vp.dumps(self.swift_grb_v2_packet) vp.prettystr(self.swift_grb_v2_packet) self.assertTrue(vp.valid_as_v2_0(self.swift_grb_v2_packet)) after = vp.dumps(self.swift_grb_v2_packet) self.assertEqual(before, after)
def test_validation_routine(self): """ Now we perform the same validation tests, but applied via the convenience functions. """ with open(datapaths.swift_bat_grb_pos_v2, 'rb') as f: v = vp.load(f) self.assertTrue(vp.valid_as_v2_0(v)) v.Who.BadChild = 42 self.assertFalse(vp.valid_as_v2_0(v)) del v.Who.BadChild self.assertTrue(vp.valid_as_v2_0(v))
def test_validation_routine(self): """ Now we perform the same validation tests, but applied via the convenience functions. """ with open(datapaths.swift_bat_grb_pos_v2, 'rb') as f: v = vp.load(f) self.assertTrue(vp.valid_as_v2_0(v)) v.Who.BadChild = 42 self.assertFalse(vp.valid_as_v2_0(v)) del v.Who.BadChild self.assertTrue(vp.valid_as_v2_0(v))
def handle_voevent(v): #Basic attribute access print("Ivorn:", v.attrib['ivorn']) print("Role:", v.attrib['role']) print( "AuthorIVORN:", v.Who.AuthorIVORN) print( "Short name:", v.Who.Author.shortName) print( "Contact:", v.Who.Author.contactEmail) #Copying by value, and validation: print( "Original valid as v2.0? ", voeventparse.valid_as_v2_0(v)) v_copy = copy.copy(v) print( "Copy valid? ", voeventparse.valid_as_v2_0(v_copy)) #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.pull_astro_coords(v) print( "Coords:", c)
def test_autoconvert_on(self): """...but we provide some python smarts to alleviate this.""" self.v.What.append(vp.Param(name='Dead Parrot')) self.v.What.append(vp.Param(name='The Answer', value=42)) self.v.What.append(vp.Param(name='What is the time?', value=datetime.datetime.utcnow())) self.v.What.append(vp.Param(name='This is a lie', value=False)) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_autoconvert_off(self): """Param values can only be strings...""" self.v.What.append(vp.Param(name='Dead Parrot', ac=False)) self.v.What.append( vp.Param(name='The Answer', value=str(42), ac=False)) self.assertTrue(vp.valid_as_v2_0(self.v)) with self.assertRaises(TypeError): self.v.What.append(vp.Param(name='IntValue', value=42, ac=False))
def test_set_author(self): vp.set_author(self.v, title='4 Pi Sky Project', shortName='4PiSky', contactName='Tim Staley', contactEmail='*****@*****.**', contactPhone='123456789', contributor='Bob') self.assertTrue(vp.valid_as_v2_0(self.v)) self.assertEqual(self.v.Who.Author.shortName, '4PiSky')
def test_make_minimal_voevent(self): v1 = vp.Voevent(stream='voevent.soton.ac.uk/TEST', stream_id='100', role='test') self.assertTrue(vp.valid_as_v2_0(v1)) v2 = vp.Voevent(stream='voevent.soton.ac.uk/TEST', stream_id=100, role='test') self.assertEqual(v1.attrib['ivorn'], v2.attrib['ivorn'])
def test_set_author(self): vp.set_author(self.v, title='4 Pi Sky Project', shortName='4PiSky', contactName='Tim Staley', contactEmail='*****@*****.**', contactPhone='123456789', contributor='Bob') self.assertTrue(vp.valid_as_v2_0(self.v)) self.assertEqual(self.v.Who.Author.shortName, '4PiSky')
def test_make_minimal_voevent(self): v1 = vp.Voevent(stream='voevent.soton.ac.uk/TEST', stream_id='100', role='test') self.assertTrue(vp.valid_as_v2_0(v1)) v2 = vp.Voevent(stream='voevent.soton.ac.uk/TEST', stream_id=100, role='test') self.assertEqual(v1.attrib['ivorn'], v2.attrib['ivorn'])
def test_autoconvert_off(self): """Param values can only be strings...""" self.v.What.append(vp.Param(name='Dead Parrot', ac=False)) self.v.What.append( vp.Param(name='The Answer', value=str(42), ac=False)) self.assertTrue(vp.valid_as_v2_0(self.v)) with self.assertRaises(TypeError): self.v.What.append(vp.Param(name='IntValue', value=42, ac=False))
def test_autoconvert_on(self): """...but we provide some python smarts to alleviate this.""" self.v.What.append(vp.Param(name='Dead Parrot')) self.v.What.append(vp.Param(name='The Answer', value=42)) self.v.What.append(vp.Param(name='What is the time?', value=datetime.datetime.utcnow())) self.v.What.append(vp.Param(name='This is a lie', value=False)) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_add_why(self): inferences = [vp.Inference(probability=0.5, relation=None, name='Toin Coss', concept='Probability')] vp.add_why(self.v, importance=0.6, expires=datetime.datetime(2013, 1, 1), inferences=inferences) self.assertTrue(vp.valid_as_v2_0(self.v)) self.assertEqual(self.v.Why.attrib['importance'], str(0.6)) self.assertEqual(self.v.Why.Inference[0].attrib['probability'], str(0.5)) self.assertEqual(self.v.Why.Inference[0].Name, 'Toin Coss')
def test_add_why(self): inferences = [vp.Inference(probability=0.5, relation=None, name='Toin Coss', concept='Probability')] vp.add_why(self.v, importance=0.6, expires=datetime.datetime(2013, 1, 1), inferences=inferences) self.assertTrue(vp.valid_as_v2_0(self.v)) self.assertEqual(self.v.Why.attrib['importance'], str(0.6)) self.assertEqual(self.v.Why.Inference[0].attrib['probability'], str(0.5)) self.assertEqual(self.v.Why.Inference[0].Name, 'Toin Coss')
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)
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)
def test_add_How(self): descriptions = ['One sentence.', 'Another.'] vp.add_how(self.v, descriptions) self.assertEqual(len(self.v.How.Description), 2) self.assertEqual(descriptions, [self.v.How.Description[0], self.v.How.Description[1]]) refs = [vp.Reference('http://www.saltycrane.com/blog/2011/07/' 'example-parsing-xml-lxml-objectify/'), vp.Reference('http://github.com/timstaley/voevent-parse')] vp.add_how(self.v, references=refs) self.assertEqual(len(self.v.How.Reference), len(refs)) self.assertEqual([r.attrib['uri'] for r in refs], [r.attrib['uri'] for r in self.v.How.Reference]) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_add_How(self): descriptions = ['One sentence.', 'Another.'] vp.add_how(self.v, descriptions) self.assertEqual(len(self.v.How.Description), 2) self.assertEqual(descriptions, [self.v.How.Description[0], self.v.How.Description[1]]) refs = [vp.Reference('http://www.saltycrane.com/blog/2011/07/' 'example-parsing-xml-lxml-objectify/'), vp.Reference('http://github.com/timstaley/voevent-parse')] vp.add_how(self.v, references=refs) self.assertEqual(len(self.v.How.Reference), len(refs)) self.assertEqual([r.attrib['uri'] for r in refs], [r.attrib['uri'] for r in self.v.How.Reference]) self.assertTrue(vp.valid_as_v2_0(self.v))
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_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 save_xml(self, xmlname, force_pretty_print=False): ''' Check the validity of the voevent xml file and save as xmlname. ''' # check if the created event is a valid VOEvent v2.0 event if vp.valid_as_v2_0(self.v): # save to VOEvent xml if force_pretty_print: with open(xmlname, 'w') as f: if force_pretty_print: # use xml.dom.minidom to force pretty printing xml vp.voevent._return_to_standard_xml(self.v) txt = lxml.etree.tostring(self.v) f.write(parseString(txt).toprettyxml()) else: with open(xmlname, 'wb') as f: # lxml pretty printing often does not work # workaround use force_pretty_print=True vp.dump(self.v, f, pretty_print=True)
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')
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')
def NewVOEvent(dm, dm_err, width, snr, flux, ra, dec, semiMaj, semiMin, ymw16, name, importance, utc, gl, gb): z = dm/1200.0 #May change errDeg = semiMaj/60.0 # Parse UTC utc_YY = int(utc[:4]) utc_MM = int(utc[5:7]) utc_DD = int(utc[8:10]) utc_hh = int(utc[11:13]) utc_mm = int(utc[14:16]) utc_ss = float(utc[17:]) t = Time('T'.join([utc[:10], utc[11:]]), scale='utc', format='isot') mjd = t.mjd now = Time.now() mjd_now = now.mjd ivorn = ''.join([name, str(utc_hh), str(utc_mm), '/', str(mjd_now)]) v = vp.Voevent(stream='nl.astron.apertif/alert', stream_id=ivorn, role=vp.definitions.roles.test) # v = vp.Voevent(stream='nl.astron.apertif/alert', stream_id=ivorn, role=vp.definitions.roles.observation) # Author origin information vp.set_who(v, date=datetime.datetime.utcnow(), author_ivorn="nl.astron") # Author contact information vp.set_author(v, title="ASTRON ALERT FRB Detector", contactName="Leon Oostrum", contactEmail="*****@*****.**", shortName="ALERT") # Parameter definitions #Apertif-specific observing configuration %%TODO: update parameters as necessary for new obs config beam_sMa = vp.Param(name="beam_semi-major_axis", unit="MM", ucd="instr.beam;pos.errorEllipse;phys.angSize.smajAxis", ac=True, value=semiMaj) beam_sma = vp.Param(name="beam_semi-minor_axis", unit="MM", ucd="instr.beam;pos.errorEllipse;phys.angSize.sminAxis", ac=True, value=semiMin) beam_rot = vp.Param(name="beam_rotation_angle", value=0.0, unit="Degrees", ucd="instr.beam;pos.errorEllipse;instr.offset", ac=True) tsamp = vp.Param(name="sampling_time", value=0.0496, unit="ms", ucd="time.resolution", ac=True) bw = vp.Param(name="bandwidth", value=300.0, unit="MHz", ucd="instr.bandwidth", ac=True) nchan = vp.Param(name="nchan", value="1536", dataType="int", ucd="meta.number;em.freq;em.bin", unit="None") cf = vp.Param(name="centre_frequency", value=1400.0, unit="MHz", ucd="em.freq;instr", ac=True) npol = vp.Param(name="npol", value="2", dataType="int", unit="None") bits = vp.Param(name="bits_per_sample", value="8", dataType="int", unit="None") gain = vp.Param(name="gain", value=1.0, unit="K/Jy", ac=True) tsys = vp.Param(name="tsys", value=75.0, unit="K", ucd="phot.antennaTemp", ac=True) backend = vp.Param(name="backend", value="ARTS") # beam = vp.Param(name="beam", value= ) v.What.append(vp.Group(params=[beam_sMa, beam_sma, beam_rot, tsamp, bw, nchan, cf, npol, bits, gain, tsys, backend], name="observatory parameters")) #Event parameters DM = vp.Param(name="dm", ucd="phys.dispMeasure", unit="pc/cm^3", ac=True, value=dm ) # DM_err = vp.Param(name="dm_err", ucd="stat.error;phys.dispMeasure", unit="pc/cm^3", ac=True, value=dm_err) Width = vp.Param(name="width", ucd="time.duration;src.var.pulse", unit="ms", ac=True, value=width) SNR = vp.Param(name="snr", ucd="stat.snr", unit="None", ac=True, value=snr) Flux = vp.Param(name="flux", ucd="phot.flux", unit="Jy", ac=True, value=flux) Flux.Description = "Calculated from radiometer equation. Not calibrated." Gl = vp.Param(name="gl", ucd="pos.galactic.lon", unit="Degrees", ac=True, value=gl) Gb = vp.Param(name="gb", ucd="pos.galactic.lat", unit="Degrees", ac=True, value=gb) v.What.append(vp.Group(params=[DM, Width, SNR, Flux, Gl, Gb], name="event parameters")) # v.What.append(vp.Group(params=[DM, DM_err, Width, SNR, Flux, Gl, Gb], name="event parameters")) #Advanced parameters (note, change script if using a differeing MW model) mw_dm = vp.Param(name="MW_dm_limit", unit="pc/cm^3", ac=True, value=ymw16) mw_model = vp.Param(name="galactic_electron_model", value="YMW16") redshift_inferred = vp.Param(name="redshift_inferred", ucd="src.redshift", unit="None", value=z) redshift_inferred.Description = "Redshift estimated using z = DM/1200.0 (Ioka 2003)" v.What.append(vp.Group(params=[mw_dm, mw_model, redshift_inferred], name="advanced parameters")) #WhereWhen vp.add_where_when(v, coords=vp.Position2D(ra=ra, dec=dec, err=errDeg, units='deg', system=vp.definitions.sky_coord_system.utc_fk5_geo), obs_time=datetime.datetime(utc_YY,utc_MM,utc_DD,utc_hh,utc_mm,int(utc_ss), tzinfo=pytz.UTC), observatory_location="WSRT") #Why vp.add_why(v, importance=imp) v.Why.Name = name if vp.valid_as_v2_0(v): with open('%s.xml' % utc, 'wb') as f: voxml = vp.dumps(v) xmlstr = minidom.parseString(voxml).toprettyxml(indent=" ") f.write(xmlstr) print(vp.prettystr(v.Who)) print(vp.prettystr(v.What)) print(vp.prettystr(v.WhereWhen)) print(vp.prettystr(v.Why)) else: print "Unable to write file %s.xml" % name
references=vp.Reference("http://gsaweb.ast.cam.ac.uk/alerts/")) # ##And finally, ``Why``## # Finally, we can provide some information about why this even might be scientifically interesting. Gaia haven't provided a classification, but we can at least incorporate the textual description: # In[ ]: vp.add_why(v) v.Why.Description = "Fading source on top of 2MASS Galaxy (offset from bulge)" # ##Check and save## # Finally - and importantly, as discussed in the [VOEvent notes](http://voevent.readthedocs.org/en/latest/parse.html) - let's make sure that this event is really valid according to our schema: # In[ ]: vp.valid_as_v2_0(v) # Great! We can now save it to disk: # In[ ]: with open('gaia.xml', 'w') as f: vp.dump(v, f) # And we're all done. You can open the file in your favourite text editor to see what # we've produced, but note that it probably won't be particularly elegantly # formatted - an alternative option is to [open it in your browser](my_gaia.xml). # ##Advanced## # ###Free-style element authoring### # Note that if you want to do something that's not part of the standard use-cases addressed by voevent-parse,
def test_set_who_minimal(self): vp.set_who(self.v, self.date, author_ivorn='voevent.soton.ac.uk/TEST') self.assertTrue(vp.valid_as_v2_0(self.v))
from voeventparse.fixtures.datapaths import swift_bat_grb_pos_v2 pp = pprint.PrettyPrinter() with open(swift_bat_grb_pos_v2, 'rb') as f: v = voeventparse.load(f) # Basic attribute access print("Ivorn:", v.attrib['ivorn']) print("Role:", v.attrib['role']) print("AuthorIVORN:", v.Who.AuthorIVORN) print("Short name:", v.Who.Author.shortName) print("Contact:", v.Who.Author.contactEmail) # Copying by value, and validation: print("Original valid as v2.0? ", voeventparse.valid_as_v2_0(v)) v_copy = copy.copy(v) print("Copy valid? ", voeventparse.valid_as_v2_0(v_copy)) # 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
# ##And finally, ``Why``## # Finally, we can provide some information about why this even might be scientifically interesting. Gaia haven't provided a classification, but we can at least incorporate the textual description: # In[ ]: vp.add_why(v) v.Why.Description = "Fading source on top of 2MASS Galaxy (offset from bulge)" # ##Check and save## # Finally - and importantly, as discussed in the [VOEvent notes](http://voevent.readthedocs.org/en/latest/parse.html) - let's make sure that this event is really valid according to our schema: # In[ ]: vp.valid_as_v2_0(v) # Great! We can now save it to disk: # In[ ]: with open('gaia.xml', 'w') as f: vp.dump(v, f) # And we're all done. You can open the file in your favourite text editor to see what # we've produced, but note that it probably won't be particularly elegantly # formatted - an alternative option is to [open it in your browser](my_gaia.xml). # ##Advanced##
def _NewVOEvent(self, dm, dm_err, width, snr, flux, ra, dec, semiMaj, semiMin, ymw16, name, importance, utc, gl, gb, gain, dt=TSAMP.to(u.ms).value, delta_nu_MHz=(BANDWIDTH / NCHAN).to(u.MHz).value, nu_GHz=1.37, posang=0, test=None): """ Create a VOEvent :param float dm: Dispersion measure (pc cm**-3) :param float dm_err: Error on DM (pc cm**-3) :param float width: Pulse width (ms) :param float snr: Signal-to-noise ratio :param float flux: flux density (mJy) :param float ra: Right ascension (deg) :param float dec: Declination (deg) :param float semiMaj: Localisation region semi-major axis (arcmin) :param float semiMin: Localisation region semi-minor axis (arcmin) :param float ymw16: YMW16 DM (pc cm**-3) :param str name: Source name :param float importance: Trigger importance (0-1) :param str utc: UTC arrival time in ISOT format :param float gl: Galactic longitude (deg) :param float gb: Galactic latitude (deg) :param float gain: Telescope gain (K Jy**-1) :param float dt: Telescope time resolution (ms) :param float delta_nu_MHz: Telescope frequency channel width (MHz) :param float nu_GHz: Telescope centre frequency (GHz) :param float posang: Localisation region position angle (deg) :param bool test: Whether to send a test event or observation event """ z = dm / 1000.0 # May change errDeg = semiMaj / 60.0 # Parse UTC utc_YY = int(utc[:4]) utc_MM = int(utc[5:7]) utc_DD = int(utc[8:10]) utc_hh = int(utc[11:13]) utc_mm = int(utc[14:16]) utc_ss = float(utc[17:]) t = Time(utc, scale='utc', format='isot') # IERS server is down, avoid using it t.delta_ut1_utc = 0 mjd = t.mjd ivorn = ''.join([name, str(utc_hh), str(utc_mm), '/', str(mjd)]) # use default value for test flag if not set if test is None: test = self.test # Set role to either test or real observation if test: self.logger.info("Event type is test") v = vp.Voevent(stream='nl.astron.apertif/alert', stream_id=ivorn, role=vp.definitions.roles.test) else: self.logger.info("Event type is observation") v = vp.Voevent(stream='nl.astron.apertif/alert', stream_id=ivorn, role=vp.definitions.roles.observation) # Author origin information vp.set_who(v, date=datetime.datetime.utcnow(), author_ivorn="nl.astron") # Author contact information vp.set_author(v, title="ARTS FRB alert system", contactName="Leon Oostrum", contactEmail="*****@*****.**", shortName="ALERT") # Parameter definitions # Apertif-specific observing configuration beam_sMa = vp.Param(name="beam_semi-major_axis", unit="MM", ucd="instr.beam;pos.errorEllipse;phys.angSize.smajAxis", ac=True, value=semiMaj) beam_sma = vp.Param(name="beam_semi-minor_axis", unit="MM", ucd="instr.beam;pos.errorEllipse;phys.angSize.sminAxis", ac=True, value=semiMin) beam_rot = vp.Param(name="beam_rotation_angle", value=str(posang), unit="Degrees", ucd="instr.beam;pos.errorEllipse;instr.offset", ac=True) tsamp = vp.Param(name="sampling_time", value=str(dt), unit="ms", ucd="time.resolution", ac=True) bw = vp.Param(name="bandwidth", value=str(delta_nu_MHz), unit="MHz", ucd="instr.bandwidth", ac=True) nchan = vp.Param(name="nchan", value=str(NCHAN), dataType="int", ucd="meta.number;em.freq;em.bin", unit="None") cf = vp.Param(name="centre_frequency", value=str(1000 * nu_GHz), unit="MHz", ucd="em.freq;instr", ac=True) npol = vp.Param(name="npol", value="2", dataType="int", unit="None") bits = vp.Param(name="bits_per_sample", value="8", dataType="int", unit="None") gain = vp.Param(name="gain", value=str(gain), unit="K/Jy", ac=True) tsys = vp.Param(name="tsys", value=str(TSYS.to(u.Kelvin).value), unit="K", ucd="phot.antennaTemp", ac=True) backend = vp.Param(name="backend", value="ARTS") # beam = vp.Param(name="beam", value= ) v.What.append(vp.Group(params=[beam_sMa, beam_sma, beam_rot, tsamp, bw, nchan, cf, npol, bits, gain, tsys, backend], name="observatory parameters")) # Event parameters DM = vp.Param(name="dm", ucd="phys.dispMeasure", unit="pc/cm^3", ac=True, value=str(dm)) DM_err = vp.Param(name="dm_err", ucd="stat.error;phys.dispMeasure", unit="pc/cm^3", ac=True, value=str(dm_err)) Width = vp.Param(name="width", ucd="time.duration;src.var.pulse", unit="ms", ac=True, value=str(width)) SNR = vp.Param(name="snr", ucd="stat.snr", unit="None", ac=True, value=str(snr)) Flux = vp.Param(name="flux", ucd="phot.flux", unit="Jy", ac=True, value=str(flux)) Flux.Description = "Calculated from radiometer equation. Not calibrated." Gl = vp.Param(name="gl", ucd="pos.galactic.lon", unit="Degrees", ac=True, value=str(gl)) Gb = vp.Param(name="gb", ucd="pos.galactic.lat", unit="Degrees", ac=True, value=str(gb)) # v.What.append(vp.Group(params=[DM, Width, SNR, Flux, Gl, Gb], name="event parameters")) v.What.append(vp.Group(params=[DM, DM_err, Width, SNR, Flux, Gl, Gb], name="event parameters")) # Advanced parameters (note, change script if using a differeing MW model) mw_dm = vp.Param(name="MW_dm_limit", unit="pc/cm^3", ac=True, value=str(ymw16)) mw_model = vp.Param(name="galactic_electron_model", value="YMW16") redshift_inferred = vp.Param(name="redshift_inferred", ucd="src.redshift", unit="None", value=str(z)) redshift_inferred.Description = "Redshift estimated using z = DM/1000.0" v.What.append(vp.Group(params=[mw_dm, mw_model, redshift_inferred], name="advanced parameters")) # WhereWhen vp.add_where_when(v, coords=vp.Position2D(ra=ra, dec=dec, err=errDeg, units='deg', system=vp.definitions.sky_coord_system.utc_fk5_geo), obs_time=datetime.datetime(utc_YY, utc_MM, utc_DD, utc_hh, utc_mm, int(utc_ss), tzinfo=pytz.UTC), observatory_location="WSRT") # Why vp.add_why(v, importance=importance) v.Why.Name = name if vp.valid_as_v2_0(v): with open('{}.xml'.format(utc), 'wb') as f: voxml = vp.dumps(v) xmlstr = minidom.parseString(voxml).toprettyxml(indent=" ") f.write(xmlstr.encode()) self.logger.info(vp.prettystr(v.Who)) self.logger.info(vp.prettystr(v.What)) self.logger.info(vp.prettystr(v.WhereWhen)) self.logger.info(vp.prettystr(v.Why)) else: self.logger.error("Unable to write file {}.xml".format(name))
def test_set_who_date(self): vp.set_who(self.v, self.date) self.assertTrue(vp.valid_as_v2_0(self.v))
def test_set_who_minimal(self): vp.set_who(self.v, self.date, author_ivorn='voevent.soton.ac.uk/TEST') self.assertTrue(vp.valid_as_v2_0(self.v))
def test_set_who_date(self): vp.set_who(self.v, self.date) self.assertTrue(vp.valid_as_v2_0(self.v))