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 set_why(self): ''' Add Why section to voevent object. ''' # Why section (optional) allows for speculation on probable # astrophysical cause if self.event['detected']: vp.add_why(self.v, inferences=vp.Inference(relation='detected', name=self.event['name'])) else: vp.add_why(self.v, inferences=vp.Inference(name=self.event['name']))
# Prettyprint some sections for desk-checking: print("\n***Here is your WhereWhen:***\n") print(vp.prettystr(v.WhereWhen)) 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)
# We should also describe how this transient was detected, and refer to the name # that Gaia have assigned it. Note that we can provide multiple descriptions # (and/or references) here: # In[ ]: vp.add_how(v, descriptions=['Scraped from the Gaia website', 'This is Gaia14adi'], 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)
print("\n***Here is your WhereWhen:***\n") print(vp.prettystr(v.WhereWhen)) 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:
# that Gaia have assigned it. Note that we can provide multiple descriptions # (and/or references) here: # In[ ]: vp.add_how(v, descriptions=['Scraped from the Gaia website', 'This is Gaia14adi'], 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[ ]:
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
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
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))