예제 #1
0
class Events(object):
    """
    A dictionary with all superevents from the Grace database.
    """

    def __init__(self):
        self.client = GraceDb()
        self.data = {}
        self.loop = asyncio.get_event_loop()
        self.loop.create_task(self._periodic_event_updater())

    def update_all(self):
        """
        Get the latest events from the Grace database.

        Returns
        -------
        None

        See Also
        --------
        https://gracedb.ligo.org/latest/
        """
        events = self.client.superevents(query="-ADVNO", orderby=["-created"])
        self.data = {}

        logging.info("Updating all events. This might take a minute.")
        start = time.time()
        for i, event in enumerate(events, 1):
            self._add_to_event_data(event)

        end = time.time()
        logging.info(f"Updating {i} events took {round(end - start, 2)} s.")

    def update_events_last_week(self):
        logging.info("Updating all events until 1 week ago. This might take a minute.")
        start = time.time()
        events = self.client.superevents(
            query="created: 1 week ago .. now -ADVNO", orderby=["-created"]
        )

        for i, event in enumerate(events, 1):
            logging.info(f"Updating event {event['superevent_id']}")
            self._add_to_event_data(event)

        end = time.time()
        logging.info(f"Updating {i} events took {round(end - start, 2)} s.")

    def update_single(self, event_id: str):
        """
        Update and store the data of a single event in the event dictionary.

        Parameters
        ----------
        event_id : str

        Returns
        -------

        """
        # Make sure the event id has the right upper and lower case format
        _event_id = event_id[0].upper() + event_id[1:].lower()

        start = time.time()
        try:
            event = self.client.superevent(_event_id)
            event = event.json()
        except (ligo.gracedb.exceptions.HTTPError, urllib.error.HTTPError) as e:
            logging.error(f"Could not find event {_event_id}. Exception: {e}")
            return
        end = time.time()
        logging.info(
            f"Updating single event from database took {round(end - start, 2)} s."
        )

        self._add_to_event_data(event)

    def _add_to_event_data(self, event):
        event_id = event.pop("superevent_id")
        event["created"] = dateutil.parser.parse(event["created"])
        self.data[event_id] = event

        self._add_event_info_from_voevent(event_id)

    def _add_event_info_from_voevent(self, event_id: str):
        voevent = VOEventFromEventId()
        try:
            voevent.get(event_id)
            self._add_event_distance(voevent)
            self._add_event_classification(voevent)
            self._add_instruments(voevent)
        except (ligo.gracedb.exceptions.HTTPError, urllib.error.HTTPError) as e:
            logging.warning(
                f"Couldn't get info from VOEvent file with event id {event_id}"
                f"Exception: {e}"
            )

    def _add_event_distance(self, voevent: VOEvent):
        """
        Add distance and its standard deviation to the event dictionary.

        Parameters
        ----------
        voevent : VOEvent

        Returns
        -------
        None
        """
        self.data[voevent.id]["distance_mean_Mly"] = voevent.distance
        self.data[voevent.id]["distance_std_Mly"] = voevent.distance_std

    def _add_event_classification(self, voevent: VOEvent):
        """
        Adds the event type to the events dictionary.

        Possible event types are binary black hole merger, black hole neutron
        star merger etc.

        Returns
        -------
        None
        """
        self.data[voevent.id]["event_types"] = voevent.p_astro
        self.data[voevent.id]["most_likely"] = self.get_likely_event_type(voevent.id)

    def _add_instruments(self, voevent: VOEvent):
        """

        Parameters
        ----------
        voevent

        Returns
        -------

        """
        self.data[voevent.id]["instruments_short"] = voevent.seen_by_short
        self.data[voevent.id]["instruments_long"] = voevent.seen_by_long

    async def _periodic_event_updater(self):
        """
        Fetches all the events from the GraceDB database.

        Returns
        -------
        None

        """
        while True:
            await asyncio.sleep(delay=36000)

            logging.info("Refreshing event database.")
            self.update_all()

    def get_likely_event_type(self, event_id: str) -> str:
        """
        Return the most likely event type of a certain event.

        Parameters
        ----------
        event_id : str
            The event ID you want to know the event type of.

        Returns
        -------
        str
            Most likely event type.
        """
        try:
            event_types = self.data[event_id]["event_types"]
            most_likely, _ = sorted(
                event_types.items(), key=lambda value: value[1], reverse=True
            )[0]
        except AttributeError:
            logging.error(f"Failed to get most likely event of {event_id}")
            return ""

        return most_likely

    @property
    def latest(self) -> Dict[str, dict]:
        """
        Return the latest event from the Grace database.

        Returns
        -------
        dict
            Latest event.
        """
        for id, info in self.data.items():
            return {id: info}

        return {"": dict()}

    def picture(self, event_id: str) -> str:
        """
        Return local path of an image from a specific event.

        Image priority is as follows: 1) LALInference 2) skymap 3) bayestar.png.

        Parameters
        ----------
        event_id : str
            The name of the event you want to have a picture of.

        Returns
        -------
        str
            Local path of the image.
        """
        files = self.client.files(event_id).json()

        for fname in ["LALInference", "skymap", "bayestar"]:
            link = get_latest_file_url(files, fname, ".png")
            if len(link) > 0:
                break

        if len(link) == 0:
            raise FileNotFoundError
        else:
            img = ImageFromUrl(link)

        return img.path
예제 #2
0
def create(name, oldname=None, gid=None, superevent=None, repo=None):
    """
    Create a new event record in the ledger..

    Parameters
    ----------
    superevent : str
       The ID of the superevent to be used from GraceDB
    name : str
       The name of the event to be recorded in the issue tracker
    names : path, optional
        The path to the name file which maps between old and new super event IDs
    oldname: str, optional
        The old name of the event.
    """
    import pathlib

    if gid or superevent:
        from ligo.gracedb.rest import GraceDb, HTTPError
        client = GraceDb(service_url=config.get("gracedb", "url"))
        r = client.ping()
    if superevent:
        data = client.superevent(superevent).json()
        event_data = client.event(data['preferred_event']).json()
        gid = data['preferred_event']
        interferometers = event_data['instruments'].split(",")
    elif gid:
        event_data = client.event(gid).json()
        interferometers = event_data['instruments'].split(",")
    else:
        event_data = None
        interferometers = []

    if gid or superevent:
        event_url = f"{config.get('gracedb', 'url')}/events/{gid}/view/"

    if not repo:
        repo = None
        #repo = f"[email protected]:pe/O3/{name}"

    event = Event(
        name=name,
        repository=repo,
        calibration={},
        interferometers=interferometers,
    )

    if oldname:
        event.meta['old superevent'] = oldname
    if gid:
        event.meta['event time'] = event_data['gpstime']
        event.meta['gid'] = gid

    working_dir = os.path.join(config.get('general', 'rundir_default'), name)

    event.meta['working directory'] = working_dir
    pathlib.Path(working_dir).mkdir(parents=True, exist_ok=True)

    if config.get("ledger", "engine") == "gitlab":
        _, repository = connect_gitlab()
        from pkg_resources import resource_filename
        issue_template = resource_filename('asimov', 'gitlabissue.md')
        gitlab.EventIssue.create_issue(repository,
                                       event,
                                       issue_template=issue_template)

    elif config.get("ledger", "engine") == "yamlfile":
        ledger = Ledger(config.get("ledger", "location"))
        ledger.add_event(event)
        ledger.save()
def get_time(superevent):
    client = GraceDb()
    response = client.superevent(superevent)
    data = response.json()
    time = float(data['t_0'])
    return time
예제 #4
0
superevent_ids = [
    superevent['superevent_id'] for superevent in superevent_iterator
]

server = gitlab.gitlab.Gitlab(config.get("gitlab", "url"),
                              private_token=config.get("gitlab", "token"))
repository = server.projects.get(config.get("olivaw", "tracking_repository"))

gitlab_events = gitlab.find_events(repository)

super_events = set(superevent_ids) - {event.title for event in gitlab_events}

# Add the new events
for superevent in list(super_events):

    data = client.superevent(superevent).json()
    event_data = client.event(data['preferred_event']).json()

    event_url = f"https://catalog-dev.ligo.org/events/{data['preferred_event']}/view/"

    event = Event(name=superevent,
                  repository=f"[email protected]:pe/O3/{superevent}",
                  gid=data['preferred_event'],
                  gid_url=event_url,
                  calibration={},
                  interferometers=event_data['instruments'].split(","),
                  disable_repo=True)
    gitlab.EventIssue.create_issue(repository,
                                   event,
                                   issue_template="scripts/outline.md")