pittgoogle.alert

Classes for working with astronomical alerts.

Alert(*[, dict, attributes, schema_name, ...])

Container for an astronomical alert.


class pittgoogle.alert.Alert(*, dict: Mapping | None = None, attributes: Mapping[str, str] | None = None, schema_name: str | None = None, msg: PubsubMessage | PubsubMessageLike | None = None, path: Path | None = None, context: google.cloud.functions_v1.context.Context | _FunctionsContextLike | None = None, dataframe: pd.DataFrame | None = None, skymap: astropy.table.Qtable | None = None)[source]

Container for an astronomical alert.

To create an Alert, use one of the from_* methods like pittgoogle.Alert.from_dict(). Instances of this class are also returned by other calls like pittgoogle.pubsub.Subscription.pull_batch().

Parameters:

property alertid: str | int

Return the alert ID. Convenience wrapper around Alert.get.

If the survey does not define an alert ID, this returns the sourceid.

property attributes: Mapping

Return the alert’s custom metadata.

If this was not provided (typical case), this attribute will contain a copy of the incoming Alert.msg.attributes. Alert IDs and schema version will be added if not already present.

You may update this dictionary as desired. If you publish this alert using pittgoogle.Topic.publish, this dictionary will be sent as the outgoing message’s Pub/Sub attributes.

property dataframe: pd.DataFrame

Return a pandas DataFrame containing the source detections.

property dec: float

Return the source’s declination. Convenience wrapper around Alert.get.

The “source” is the detection that triggered the alert.

property dict: Mapping

Alert data as a dictionary.

If this was not provided (typical case), this attribute will contain the deserialized alert bytes from Alert.msg.data.

You may update this dictionary as desired. If you publish this alert using pittgoogle.Topic.publish, this dictionary will be sent as the outgoing Pub/Sub message’s data payload.

Returns:

The alert data as a dictionary.

Return type:

dict

Raises:

SchemaError – If unable to deserialize the alert bytes.

drop_cutouts() <property object at 0x7fce83567f10>[source]

Drop the cutouts from the alert dictionary.

Returns:

The dict with the cutouts (postage stamps) removed.

Return type:

dict

classmethod from_cloud_functions(event: Mapping, context: google.cloud.functions_v1.context.Context, schema_name: str | None = None)[source]

Create an Alert from an ‘event’ and ‘context’, as received by a Cloud Functions module.

Argument definitions copied from https://cloud.google.com/functions/1stgendocs/tutorials/pubsub-1st-gen

Parameters:
  • event (dict) – The dictionary with data specific to this type of event. The @type field maps to type.googleapis.com/google.pubsub.v1.PubsubMessage. The data field maps to the PubsubMessage data in a base64-encoded string. The attributes field maps to the PubsubMessage attributes if any is present.

  • context (google.cloud.functions.Context) – Metadata of triggering event including event_id which maps to the PubsubMessage messageId, timestamp which maps to the PubsubMessage publishTime, event_type which maps to google.pubsub.topic.publish, and resource which is a dictionary that describes the service API endpoint pubsub.googleapis.com, the triggering topic’s name, and the triggering event type type.googleapis.com/google.pubsub.v1.PubsubMessage.

classmethod from_cloud_run(envelope: Mapping, schema_name: str | None = None) Alert[source]

Create an Alert from an HTTP request envelope containing a Pub/Sub message, as received by a Cloud Run module.

Parameters:
  • envelope (dict) – The HTTP request envelope containing the Pub/Sub message.

  • schema_name (str, optional) – The name of the schema to use. Defaults to None.

Returns:

An instance of the Alert class.

Return type:

Alert

Raises:

BadRequest – If the Pub/Sub message is invalid or missing.

Example

Code for a Cloud Run module that uses this method to open a ZTF alert:

import pittgoogle
# flask is used to work with HTTP requests, which trigger Cloud Run modules
# the request contains the Pub/Sub message, which contains the alert packet
import flask

app = flask.Flask(__name__)

# function that receives the request
@app.route("/", methods=["POST"])
def index():

    try:
        # unpack the alert
        # if the request does not contain a valid message, this raises a `BadRequest`
        alert = pittgoogle.Alert.from_cloud_run(envelope=flask.request.get_json(), schema_name="ztf")

    except pittgoogle.exceptions.BadRequest as exc:
        # return the error text and an HTTP 400 Bad Request code
        return str(exc), 400

    # continue processing the alert
    # when finished, return an empty string and an HTTP success code
    return "", 204
classmethod from_dict(payload: Mapping, attributes: Mapping[str, str] | None = None, schema_name: str | None = None) Alert[source]

Create an Alert object from the given payload dictionary.

Parameters:
  • payload (dict) – The dictionary containing the data for the Alert object.

  • attributes (Mapping[str, str], None) – Additional attributes for the Alert object. Defaults to None.

  • schema_name (str, None) – The name of the schema. Defaults to None.

Returns:

An instance of the Alert class.

Return type:

Alert

classmethod from_msg(msg: PubsubMessage, schema_name: str | None = None) Alert[source]

Create an Alert object from a google.cloud.pubsub_v1.types.PubsubMessage.

Parameters:
  • msg (google.cloud.pubsub_v1.types.PubsubMessage) – The PubsubMessage object to create the Alert from.

  • schema_name (str, optional) – The name of the schema to use for the Alert. Defaults to None.

Returns:

The created Alert object.

Return type:

Alert

classmethod from_path(path: str | Path, schema_name: str | None = None) Alert[source]

Create an Alert object from the file at the specified path.

Parameters:
  • path (str or Path) – The path to the file containing the alert data.

  • schema_name (str, optional) – The name of the schema to use for the alert. Defaults to None.

Returns:

An instance of the Alert class.

Return type:

Alert

Raises:
  • FileNotFoundError – If the file at the specified path does not exist.

  • IOError – If there is an error reading the file.

get(field: str, default: Any = None) Any[source]

Return the value of a field from the alert data.

Parameters:
  • field (str) – Name of a field. This must be one of the generic field names used by Pitt-Google (keys in Alert.schema.map). To use a survey-specific field name instead, use Alert.dict.get.

  • default (str, optional) – The default value to be returned if the field is not found.

Returns:

The value in the Alert.dict corresponding to the field.

Return type:

any

get_key(field: str, name_only: bool = False, default: str | None = None) str | list[str] | None[source]

Return the survey-specific field name.

Parameters:
  • field (str) – Generic field name whose survey-specific name is to be returned. This must be one of the keys in the dict self.schema.map.

  • name_only (bool) – In case the survey-specific field name is nested below the top level, whether to return just the single final name as a str (True) or the full path as a list[str] (False).

  • default (str or None) – Default value to be returned if the field is not found.

Returns:

Survey-specific name for the field, or default if the field is not found. list[str] if this is a nested field and name_only is False, else str with the final field name only.

Return type:

str or list[str])

property healpix19: int

Return the HEALPix order 19 pixel index at the source’s right ascension (RA) and declination.

See healpix29() for a more detailed explanation and an example of how HEALPix indexes can be used. The difference here is that order 19 means the pixels are larger, with a resolution (square root of area) of ~0.4 arcseconds. If this resolution is still too fine for your use case, try healpix9(). If it is too coarse, try healpix29().

The following list of pixels covers at least the same area of sky as the one in the healpix29 example (and likely more), but the total number of pixels is reduced by a factor of ~10^6 down to 549.

# See the healpix29 docstring for a complete example. The radius is 5" and
# nside19 is analogous to nside29. The length of this list is 549.
ex_dra_cone = hpgeom.query_circle(nside19, *ex_dra_coords, radius, inclusive=True)
property healpix29: int

Return the HEALPix order 29 pixel index at the source’s right ascension (RA) and declination.

Uses the nested numbering scheme for pixel indexes. Assumes RA and dec are in degrees.

This can be useful for spatial searches and cross matches because it collapses two floats (RA and dec) into one integer (pixel index), which can be much easier to work with. There is some loss of precision but it will be insignificant for most use cases – the pixel resolution (square root of area) at order 29 is ~4e-4 arcseconds. This resolution may even be higher than preferred for many use cases because it can result in a very large set of pixels that are needed to cover the area of interest. In that case, try healpix19() or healpix9().

Example

Check whether this alert is within 5 arcsec of the eclipsing cataclysmic variable EX Draconis. We recommend hpgeom <https://hpgeom.readthedocs.io/ for working with HEALPix.

import hpgeom

ex_dra_coords = (271.05995, 67.90355)  # deg
radius = 5 / 3600  # deg
nside29 = hpgeom.order_to_nside(29)

# Find the set of HEALPix order 29 pixels that cover a 5" cone centered on the target.
# The length of this list is 508,185,237.
ex_dra_cone = hpgeom.query_circle(nside29, *ex_dra_coords, radius, inclusive=True, fact=1)

# Check whether this alert is within 5" of the target.
alert.healpix29 in ex_dra_cone
property healpix9: int

Return the HEALPix order 9 pixel index at the source’s right ascension (RA) and declination.

See healpix29() for a more detailed explanation and an example of how HEALPix indexes can be used. The difference here is that order 9 means the pixels are much larger, with a resolution (square root of area) of ~400 arcseconds or ~0.1 degrees. The following list of pixels covers the same area of sky (and more) as the one in the healpix29 example, but the total number of pixels is reduced by a factor of ~10^9 down to a single pixel.

# See the healpix29 docstring for a complete example. The radius is 5" and
# nside9 is analogous to nside29. The length of this list is 1.
ex_dra_cone = hpgeom.query_circle(nside9, *ex_dra_coords, radius, inclusive=True)

If this resolution is too coarse for your use case, try healpix19() or healpix29().

property name_in_bucket: str

Name of the alert object (file) in Google Cloud Storage.

property objectid: str | int

Return the object ID. Convenience wrapper around Alert.get.

The “object” represents a collection of sources, as determined by the survey.

property ra: float

Return the source’s right ascension. Convenience wrapper around Alert.get.

The “source” is the detection that triggered the alert.

property schema: Schema

Return the schema from the pittgoogle.registry.Schemas registry.

Raises:

SchemaError – If the schema_name is not supplied or a schema with this name is not found.

property skymap: astropy.table.QTable | None

Alert skymap as an astropy Table. Currently implemented for LVK schemas only.

This skymap is loaded from the alert to an astropy table and extra columns are added, following https://emfollow.docs.ligo.org/userguide/tutorial/multiorder_skymaps.html. The table is sorted by PROBDENSITY and then UNIQ, in descending order, so that the most likely location is first. Columns:

  • UNIQ: HEALPix pixel index in the NUNIQ indexing scheme.

  • PROBDENSITY: Probability density in the pixel (per steradian).

  • nside: HEALPix nside parameter defining the pixel resolution.

  • ipix: HEALPix pixel index at resolution nside.

  • ra: Right ascension of the pixel center (radians).

  • dec: Declination of the pixel center (radians).

  • pixel_area: Area of the pixel (steradians).

  • prob: Probability density in the pixel.

  • cumprob: Cumulative probability density up to the pixel.

Examples

# most likely location
alert.skymap[0]

# 90% credible region
alert.skymap[:alert.skymap['cumprob'].searchsorted(0.9)]
property sourceid: str | int

Return the source ID. Convenience wrapper around Alert.get.

The “source” is the detection that triggered the alert.