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))
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}
def test_get_event_time_as_utc_formatted_with_timezone_plus(self): # An edge case: ISOFormat can include a timezone suffix, # e.g. '2016-09-25T11:16:48+00:00' # The VOEvent UTC format means that the suffix is redundant, # but *that doesn't necessarily mean it won't get added anyway!* asassn_time = vp.get_event_time_as_utc(self.assasn_scraped_packet) self.assertIsNotNone(asassn_time)
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 get_utc_time_str(v): ''' Get time in UTC. :param v: VOEvent xml :type v: lxml.objectify.ObjectifiedElement :returns: time as string 'YYYY-MM-DD HH:MM:SS.MS' :rtype: str ''' utctime = vp.get_event_time_as_utc(v, index=0) return utctime.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
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 __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
def test_get_event_time_as_utc_from_TDB(self): converted_isotime = vp.get_event_time_as_utc( self.gaia_noname_param_packet) # check it works, and returns timezone aware datetime: self.assertIsInstance(converted_isotime, datetime.datetime) self.assertTrue(converted_isotime.tzinfo is not None) self.assertEqual(converted_isotime.utcoffset(), datetime.timedelta(0)) self.assertEqual(converted_isotime.utcoffset(), datetime.timedelta(0)) od = self.gaia_noname_param_packet.WhereWhen.ObsDataLocation[0] ol = od.ObservationLocation coord_sys = ol.AstroCoords.attrib['coord_system_id'] self.assertEqual(coord_sys, 'TDB-ICRS-BARY') raw_iso_string = str(ol.AstroCoords.Time.TimeInstant.ISOTime) misinterpreted_as_utc = iso8601.parse_date(raw_iso_string) self.assertNotEqual(converted_isotime, misinterpreted_as_utc)
def test_get_event_time_as_utc_blank(self): # Running on an empty VOEvent should return None, not an exception: null_result = vp.get_event_time_as_utc(self.blank) self.assertIsNone(null_result)
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_time_as_utc(self): isotime = vp.get_event_time_as_utc(self.swift_grb_v2_packet) # check it works, and returns timezone aware datetime: self.assertIsInstance(isotime, datetime.datetime) self.assertTrue(isotime.tzinfo is not None) self.assertEqual(isotime.utcoffset(), datetime.timedelta(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 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