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
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
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")