def fetch_events(cls, headers, fill=True): """ Get Events from given run(s). Parameters ---------- headers : RunHeader or iterable of RunHeader The headers to fetch the events for fill : bool, optional If non-scalar data should be filled in, Defaults to True Yields ------ event : Event The event, optionally with non-scalar data filled in """ try: headers.items() except AttributeError: pass else: headers = [headers] for header in headers: descriptors = find_event_descriptors( run_start=header.run_start_uid) for descriptor in descriptors: for event in find_events(descriptor=descriptor): if fill: fill_event(event) yield event
def test_document_funcs_for_smoke(): global run_start_uid, descriptor_uid # todo this next line will break once NSLS-II/metadatastore#142 is merged run_start, = find_run_starts(uid=run_start_uid) descriptors = [desc for desc in find_event_descriptors(uid=descriptor_uid)] run_stop, = find_run_stops(uid=run_stop_uid) documents = [run_start, run_stop] documents.extend(descriptors) attrs = ['__repr__', '__str__', '_repr_html_', ] for doc, attr in product(documents, attrs): getattr(doc, attr)()
def update(self): """Obtain a fresh list of the relevant Events.""" # like fetch_events, but we don't fill in the data right away events = [] for header in self.headers: descriptors = find_event_descriptors(run_start=header.run_start_uid) for descriptor in descriptors: events.extend(list(find_events(descriptor=descriptor))) if not events: return new_events = [] for event in events: if event.uid not in self._known_uids: new_events.append(event) self._known_uids.add(event.uid) # The major performance savings is here: only fill the new events. [fill_event(event) for event in new_events] self._queue.append(new_events) # the entry can be an empty list
def from_run_start(cls, run_start, verify_integrity=True): """ Build a Header from a RunStart Document. Parameters ---------- run_start : metadatastore.document.Document Returns ------- header : dataportal.broker.Header """ header = Header() header._name = "Header" header.event_descriptors = list( find_event_descriptors(run_start=run_start)) run_stops = list(find_run_stops(run_start=run_start.uid)) try: run_stop, = run_stops except ValueError: num = len(run_stops) run_stop = None if num == 0: error_msg = ("A RunStop record could not be found for the " "run with run_start_uid {0}".format(run_start.uid)) warnings.warn(error_msg) else: error_msg = ( "{0} RunStop records (uids {1}) were found for the run " "with run_start_uid {2}".format( num, [rs.uid for rs in run_stops], run_start.uid)) if verify_integrity: raise IntegrityError(error_msg) else: warnings.warn(error_msg) # Map keys from RunStart and RunStop onto Header. run_start_renames = {'start_time': 'time', 'start_datetime': 'time_as_datetime', 'scan_id': 'scan_id', 'beamline_id': 'beamline_id', 'owner': 'owner', 'group': 'group', 'project': 'project', 'run_start_id': 'id', 'run_start_uid': 'uid'} run_start_renames_back = {v: k for k, v in run_start_renames.items()} for k in run_start: new_key = run_start_renames_back.get(k, k) header[new_key] = run_start[k] if run_stop is not None: run_stop_renames = {'stop_time': 'time', 'stop_datetime': 'time_as_datetime', 'exit_reason': 'reason', 'exit_status': 'exit_status', 'run_stop_id': 'id', 'run_stop_uid': 'uid'} run_stop_renames_back = {v: k for k, v in run_stop_renames.items()} for k in run_stop: new_key = run_stop_renames_back.get(k, k) header[new_key] = run_stop[k] del header['run_start'] run_start._name = 'Header' # Strip unuseful recursion. We don't mess with underlying Documents, # but the header is a special case, and the repr should reflect # its structure accurately. for ev_desc in header.event_descriptors: ev_desc.run_start = ev_desc.run_start.uid return header
def find_headers(cls, **kwargs): """Given search criteria, find Headers describing runs. This function returns a list of dictionary-like objects encapsulating the metadata for a run -- start time, instruments uses, and so on. In addition to the Parameters below, advanced users can specifiy arbitrary queries that are passed through to mongodb. Parameters ---------- start_time : time-like, optional Include Headers for runs started after this time. Valid "time-like" representations are: - float timestamps (seconds since 1970), such as time.time() - '2015' - '2015-01' - '2015-01-30' - '2015-03-30 03:00:00' - Python datetime objects, such as datetime.datetime.now() stop_time: time-like, optional Include Headers for runs started before this time. See `start_time` above for examples. beamline_id : str, optional String identifier for a specific beamline project : str, optional Project name owner : str, optional The username of the logged-in user when the scan was performed scan_id : int, optional Integer scan identifier uid : str, optional Globally unique id string provided to metadatastore _id : str or ObjectId, optional The unique id generated by mongo data_key : str, optional The alias (e.g., 'motor1') or PV identifier of data source Returns ------- data : list Header objects Examples -------- >>> find_headers(start_time='2015-03-05', stop_time='2015-03-10') >>> find_headers(data_key='motor1') >>> find_headers(data_key='motor1', start_time='2015-03-05') """ data_key = kwargs.pop('data_key', None) run_start = find_run_starts(**kwargs) if data_key is not None: node_name = 'data_keys.{0}'.format(data_key) query = {node_name: {'$exists': True}} descriptors = [] for rs in run_start: descriptor = find_event_descriptors(run_start=rs, **query) for d in descriptor: descriptors.append(d) # query = {node_name: {'$exists': True}, # 'run_start_id': {'$in': [ObjectId(rs.id) for rs in run_start]}} # descriptors = find_event_descriptors(**query) result = [] known_uids = deque() for descriptor in descriptors: if descriptor.run_start.uid not in known_uids: rs = descriptor.run_start known_uids.append(rs.uid) result.append(rs) run_start = result result = [] for rs in run_start: result.append(Header.from_run_start(rs)) return Headers(result)