def test_Event(): # set/get/del, index # dict methods e = Events() r = MockRecording() d = {"a": 1, "b": "hello", "c": True} ev1 = e.add_event(r, 1, 10, 12, d) assert ev1.recording is r assert ev1.span_id == 1 assert ev1.start_idx == 10 assert ev1.stop_idx == 12 assert dict(ev1.iteritems()) == d ev1["added"] = True assert ev1["added"] == True assert_raises(KeyError, ev1.__getitem__, "notadded") assert_raises(KeyError, ev1.__delitem__, "notadded") del ev1["added"] assert_raises(KeyError, ev1.__getitem__, "added") assert_raises(KeyError, ev1.__delitem__, "added") assert "a" in ev1 assert "added" not in ev1 assert_raises(ValueError, ev1.__setitem__, "c", "asdf") assert ev1["c"] == True assert ev1.get("c") == True assert ev1.get("notadded") is None assert ev1.get("notadded", 10) == 10 assert sorted(list(ev1)) == ["a", "b", "c"] assert sorted(ev1.iterkeys()) == ["a", "b", "c"] assert sorted(ev1.itervalues()) == sorted(d.itervalues()) assert list(ev1.iterkeys()) == ev1.keys() assert list(ev1.itervalues()) == ev1.values() assert list(ev1.iteritems()) == ev1.items() assert ev1.has_key("a") assert not ev1.has_key("z") assert ev1.overlaps(ev1) assert not ev1.overlaps(MockRecording(), 1, 9, 11) assert not ev1.overlaps(r, 0, 9, 11) assert ev1.overlaps(r, 1, 9, 11) assert ev1.overlaps(r, 1, 10, 12) assert ev1.overlaps(r, 1, 10, 11) assert ev1.overlaps(r, 1, 11, 12) assert not ev1.overlaps(r, 1, 0, 2) assert not ev1.overlaps(r, 1, 100, 102) # Check half-openness assert not ev1.overlaps(r, 0, 9, 10) assert not ev1.overlaps(r, 0, 12, 15) # Nothing overlaps an empty interval assert not ev1.overlaps(r, 0, 11, 11) assert len(e) == 1 ev1.delete() assert len(e) == 0 # XX: maybe this should be a ValueError or something, but checking for # whether the event object itself exists in __getitem__ is extra work that # doesn't seem worth bothering with. assert_raises(KeyError, ev1.__getitem__, "a")
def test_Event_relative(): e = Events() r = MockRecording() ev20 = e.add_event(r, 0, 20, 21, {"a": 20, "extra": True}) ev10 = e.add_event(r, 0, 10, 11, {"a": 10}) ev30 = e.add_event(r, 0, 30, 31, {"a": 30}) ev40 = e.add_event(r, 0, 40, 41, {"a": 40, "extra": True}) assert ev20.relative(1)["a"] == 30 assert_raises(IndexError, ev20.relative, 0) assert ev20.relative(-1)["a"] == 10 assert ev10.relative(2)["a"] == 30 assert ev30.relative(-2)["a"] == 10 assert ev10.relative(1, "extra")["a"] == 20 assert ev10.relative(2, "extra")["a"] == 40
def test_Events_basic(): # load/store of different types # errors on type mismatches # storing None e = Events() r = MockRecording() ev1 = e.add_event(r, 0, 10, 11, {"a": 1, "b": "hello", "c": True}) assert ev1.recording is r assert ev1.span_id == 0 assert ev1.start_idx == 10 assert ev1.stop_idx == 11 assert ev1["a"] == 1 assert ev1["b"] == "hello" assert ev1["c"] == True assert type(ev1["a"]) == int assert type(ev1["b"]) == str assert type(ev1["c"]) == bool assert dict(ev1) == {"a": 1, "b": "hello", "c": True} ev1["a"] = 2 assert ev1["a"] == 2 assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"a": "string"}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"a": True}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"b": 10}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"b": True}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"c": 10}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"c": "string"}) ev1["a"] = None assert ev1["a"] is None ev1["xxx"] = None ev2 = e.add_event(r, 0, 11, 12, {"xxx": 3}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"xxx": "string"}) assert_raises(ValueError, e.add_event, r, 0, 20, 21, {"xxx": True}) assert ev2["xxx"] == 3 assert ev2.start_idx == 11 assert ev1["xxx"] is None e_pick = cPickle.loads(cPickle.dumps(e)) ev1_pick, ev2_pick = list(e_pick) assert isinstance(ev1_pick.recording, MockRecording) assert ev1_pick.span_id == 0 assert ev1_pick.start_idx == 10 assert ev1_pick.stop_idx == 11 assert ev1_pick.items() == ev1.items() assert isinstance(ev2_pick.recording, MockRecording) assert ev2_pick.span_id == 0 assert ev2_pick.start_idx == 11 assert ev2_pick.stop_idx == 12 assert ev2_pick.items() == ev2.items()
def test_Event_move(): e = Events() r = MockRecording() ev20 = e.add_event(r, 0, 20, 21, {"a": 20, "extra": True}) ev10 = e.add_event(r, 0, 10, 15, {"a": 10}) assert ev20.start_idx == 20 assert ev20.stop_idx == 21 assert ev20.relative(-1)["a"] == 10 ev20.move(-15) assert ev20.start_idx == 5 assert ev20.stop_idx == 6 assert ev20.relative(1)["a"] == 10 assert ev10.start_idx == 10 assert ev10.stop_idx == 15 ev10.move(5) assert ev10.start_idx == 15 assert ev10.stop_idx == 20
def test_recspan(): e = Events() r0 = e.add_recspan_info(0, 100, {"a": 1}) r1 = e.add_recspan_info(1, 200, {"a": 2, "b": "hi"}) assert r0.id == 0 assert r0.ticks == 100 assert r0["a"] == 1 assert_raises(KeyError, r0.__getitem__, "b") assert r1.id == 1 assert r1.ticks == 200 assert r1["a"] == 2 assert r1["b"] == "hi" assert list(e._all_recspan_infos()) == [r0, r1] assert r0 != r1 # smoke test repr(r0)
def test_python_query_typechecking(): e = Events() r = MockRecording() e.add_event(r, 0, 10, 11, { "a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None }) p = e.placeholder assert list(e.find(p["e"] == 1)) == [] assert len(list(e.find(p["e"] == None))) == 1 for bad in (True, "asdf", r): assert_raises(EventsError, p["a"].__eq__, bad) assert_raises(EventsError, p["a"].__gt__, bad) assert_raises(EventsError, p["a"].__lt__, bad) assert_raises(EventsError, p["a"].__le__, bad) assert_raises(EventsError, p["a"].__ge__, bad) assert_raises(EventsError, p["a"].__and__, p["c"]) assert_raises(EventsError, p["a"].__and__, p["c"]) assert_raises(EventsError, p["a"].__invert__) assert_raises(EventsError, e.find, p["e"])
def test_EventSet(): e = Events() r = MockRecording() e.add_event(r, 0, 10, 11, {"a": 1, "b": True, "c": None}) e.add_event(r, 0, 20, 21, {"a": -1, "b": True}) e.add_event(r, 0, 15, 16, {"a": -1, "b": False, "c": 1}) es = e.find() assert es[0].start_idx == 10 assert es[1].start_idx == 15 assert es[2].start_idx == 20 assert es[-1].start_idx == 20 assert_raises(IndexError, es.__getitem__, 3) a_series = es["a"] assert np.all(a_series == [1, -1, -1]) assert a_series.dtype == np.dtype(int) b_series = es["b"] assert np.all(b_series == [True, False, True]) assert b_series.dtype == np.dtype(bool) assert_raises(KeyError, es.__getitem__, "c")
def test_None_types(): e = Events() e.add_recspan_info(0, 100, {}) # This used to be broken for bools in particular e1 = e.add_event(0, 10, 11, {"bool": None, "num": None, "blob": None}) e2 = e.add_event(0, 11, 12, {"bool": True, "num": 15, "blob": "asdf"}) e3 = e.add_event(0, 12, 13, {"bool": None, "num": None, "blob": None}) assert dict(e1) == {"bool": None, "num": None, "blob": None} assert dict(e2) == {"bool": True, "num": 15, "blob": "asdf"} assert dict(e3) == {"bool": None, "num": None, "blob": None}
def test_matches(): e = Events() e.add_recspan_info(0, 100, {}) e1 = e.add_event(0, 10, 11, {"a": 1, "b": "hi"}) e2 = e.add_event(0, 20, 21, {"a": 2, "b": "hi"}) assert e1.matches("a == 1") assert not e1.matches("a == 2") assert e2.matches("a == 2") assert not e2.matches("a == 1") p = e.placeholder_event() assert list(p.matches("a == 1")) == [e1]
def test_Event_relative(): e = Events() e.add_recspan_info(0, 100, {}) e.add_recspan_info(1, 100, {}) ev20 = e.add_event(0, 20, 21, {"a": 20, "extra": True}) ev10 = e.add_event(0, 10, 11, {"a": 10}) ev30 = e.add_event(0, 30, 31, {"a": 30}) ev40 = e.add_event(0, 40, 41, {"a": 40, "extra": True}) ev1_40 = e.add_event(1, 40, 41, {"a": 140, "extra": False}) assert ev20.relative(1)["a"] == 30 assert_raises(IndexError, ev20.relative, 0) assert ev20.relative(-1)["a"] == 10 assert ev10.relative(2)["a"] == 30 assert ev30.relative(-2)["a"] == 10 assert ev10.relative(1, "extra")["a"] == 20 assert ev10.relative(2, "extra")["a"] == 40 # Can't cross into different recspans assert_raises(IndexError, ev40.relative, 1) assert_raises(IndexError, ev1_40.relative, -1)
def test_Event_move(): e = Events() e.add_recspan_info(0, 100, {}) ev20 = e.add_event(0, 20, 21, {"a": 20, "extra": True}) ev10 = e.add_event(0, 10, 15, {"a": 10}) assert ev20.start_tick == 20 assert ev20.stop_tick == 21 assert ev20.relative(-1)["a"] == 10 ev20.move(-15) assert ev20.start_tick == 5 assert ev20.stop_tick == 6 assert ev20.relative(1)["a"] == 10 assert ev10.start_tick == 10 assert ev10.stop_tick == 15 ev10.move(5) assert ev10.start_tick == 15 assert ev10.stop_tick == 20
def test_python_query_typechecking(): e = Events() e.add_recspan_info(0, 100, {}) e.add_event(0, 10, 11, {"a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None}) p = e.placeholder_event() assert list(p["e"] == 1) == [] assert len(list(p["e"] == None)) == 1 for bad in (True, "asdf"): assert_raises(EventsError, p["a"].__eq__, bad) assert_raises(EventsError, p["a"].__gt__, bad) assert_raises(EventsError, p["a"].__lt__, bad) assert_raises(EventsError, p["a"].__le__, bad) assert_raises(EventsError, p["a"].__ge__, bad) assert_raises(EventsError, p["a"].__and__, p["c"]) assert_raises(EventsError, p["a"].__and__, p["c"]) assert_raises(EventsError, p["a"].__invert__) assert_raises(EventsError, list, p["e"])
def test_python_query(): # all operators # types (esp. including None) # index e = Events() r1 = MockRecording() r2 = MockRecording() ev10 = e.add_event(r1, 0, 10, 11, { "a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None }) ev20 = e.add_event(r1, 1, 20, 25, { "a": -1, "b": "fdsa", "c": False, "d": -3.14, "e": None }) ev21 = e.add_event(r2, 0, 21, 26, { "a": 1, "b": "asdf", "c": False, "d": -3.14, "e": 123 }) p = e.placeholder def t(q, expected): assert [ev.start_idx for ev in e.find(q)] == expected t(p.start_idx == 10, [10]) t(p.start_idx != 10, [20, 21]) t(p.start_idx < 10, []) t(p.start_idx > 10, [20, 21]) t(p.start_idx >= 20, [20, 21]) t(p.start_idx <= 20, [10, 20]) t(~(p.start_idx == 20), [10, 21]) t(~(p.start_idx != 20), [20]) t(p.recording == r1, [10, 20]) t(p.recording == r2, [21]) assert_raises(EventsError, p.recording.__eq__, 1) assert_raises(EventsError, p.start_idx.__eq__, r1) t(p["a"] == 1, [10, 21]) t(p["a"] != 1, [20]) t(p["a"] < 1, [20]) t(p["a"] > 1, []) t(p["a"] >= 1, [10, 21]) t(p["a"] <= 1, [10, 20, 21]) t(~(p["a"] == 1), [20]) t(~(p["a"] != 1), [10, 21]) t(p["a"] == 1.5, []) t(p["a"] < 1.5, [10, 20, 21]) t(p["a"] < 0.5, [20]) t(p["a"] > 0.5, [10, 21]) t(p["b"] == "asdf", [10, 21]) t(p["b"] != "asdf", [20]) t(p["b"] < "asdf", []) t(p["b"] > "asdf", [20]) t(p["b"] >= "asdf", [10, 20, 21]) t(p["b"] <= "asdf", [10, 21]) t(p["b"] <= "b", [10, 21]) t(p["b"] >= "b", [20]) t(~(p["b"] == "asdf"), [20]) t(~(p["b"] != "asdf"), [10, 21]) t(p["c"] == True, [10]) t(p["c"] != True, [20, 21]) t(p["c"] == False, [20, 21]) t(p["c"] != False, [10]) t(p["c"], [10]) t(~p["c"], [20, 21]) t(p["c"] < True, [20, 21]) t(p["c"] <= True, [10, 20, 21]) t(p["c"] > True, []) t(p["c"] > False, [10]) t(p["c"] >= False, [10, 20, 21]) t(~(p["c"] == True), [20, 21]) t(~(p["c"] != True), [10]) t(p["d"] == 1.5, [10]) t(p["d"] != 1.5, [20, 21]) t(p["d"] < 1.5, [20, 21]) t(p["d"] > 1.5, []) t(p["d"] >= 1.5, [10]) t(p["d"] <= 1.5, [10, 20, 21]) t(~(p["d"] == 1.5), [20, 21]) t(~(p["d"] != 1.5), [10]) t(p["d"] == 1, []) t(p["d"] < 10, [10, 20, 21]) t(p["d"] < 1, [20, 21]) t(p["d"] > 1, [10]) t(p["e"] == None, [10, 20]) t(p["e"] != None, [21]) t(p.has_key("e"), [10, 20, 21]) t(~p.has_key("e"), []) t(p["nonexistent"] == 10, []) t(p["nonexistent"] != 10, []) t(p["nonexistent"] == None, []) t(p.has_key("nonexistent"), []) t(~p.has_key("nonexistent"), [10, 20, 21]) t(p["a"] > p["d"], [20, 21]) t(p["a"] < p["d"], [10]) t((p.start_idx < 21) & (p["a"] == 1), [10]) t((p.start_idx < 21) | (p["a"] == 1), [10, 20, 21]) t(~((p.start_idx < 21) & (p["a"] == 1)), [20, 21]) t(~((p.start_idx < 21) | (p["a"] == 1)), []) t(p.overlaps(ev10), [10]) t(p.overlaps(ev20), [20]) t(p.overlaps(ev21), [21]) t(p.overlaps(r1, 0, 5, 10), []) t(p.overlaps(r1, 0, 5, 11), [10]) t(p.overlaps(r1, 0, 11, 20), []) t(p.overlaps(r1, 0, 11, 100), []) for i in xrange(20, 25): t(p.overlaps(r1, 1, i, i + 1), [20])
def test_find(): # all the different calling conventions e = Events() r = MockRecording("asdf") e.add_event(r, 0, 10, 11, {"a": 1, "b": True}) e.add_event(r, 0, 20, 21, {"a": -1, "b": True}) assert [ev.start_idx for ev in e.find()] == [10, 20] assert [ev.start_idx for ev in e.find({"a": 1})] == [10] assert [ev.start_idx for ev in e.find({"a": 1, "b": True})] == [10] assert [ev.start_idx for ev in e.find({"a": 1, "b": False})] == [] assert [ev.start_idx for ev in e.find({"b": True})] == [10, 20] assert [ev.start_idx for ev in e.find({"_RECORDING": MockRecording()})] == [] assert [ev.start_idx for ev in e.find({"_RECORDING": r})] == [10, 20] assert [ev.start_idx for ev in e.find({"_SPAN_ID": 0})] == [10, 20] assert [ev.start_idx for ev in e.find({"_SPAN_ID": 1})] == [] assert [ev.start_idx for ev in e.find({"_START_IDX": 10})] == [10] assert [ev.start_idx for ev in e.find({"_STOP_IDX": 11})] == [10] assert [ev.start_idx for ev in e.find({"_RECORDING_NAME": "asdf"})] == [10, 20] assert [ev.start_idx for ev in e.find({"_RECORDING_NAME": "fdsa"})] == [] assert [ev.start_idx for ev in e.find(e.placeholder["a"] == 1)] == [10]
def test_events_method(): # all the different calling conventions e = Events() e.add_recspan_info(0, 100, {}) e.add_event(0, 10, 11, {"a": 1, "b": True}) e.add_event(0, 20, 21, {"a": -1, "b": True}) assert [ev.start_tick for ev in e.events_query()] == [10, 20] assert [ev.start_tick for ev in e.events_query(True)] == [10, 20] assert not list(e.events_query(False)) assert [ev.start_tick for ev in e.events_query({"a": 1})] == [10] assert [ev.start_tick for ev in e.events_query({"a": 1, "b": True})] == [10] assert [ev.start_tick for ev in e.events_query({"a": 1, "b": False})] == [] assert [ev.start_tick for ev in e.events_query({"b": True})] == [10, 20] assert [ev.start_tick for ev in e.events_query({"_RECSPAN_ID": 0})] == [10, 20] assert [ev.start_tick for ev in e.events_query({"_RECSPAN_ID": 1})] == [] assert [ev.start_tick for ev in e.events_query({"_START_TICK": 10})] == [10] assert [ev.start_tick for ev in e.events_query({"_STOP_TICK": 11})] == [10] assert [ev.start_tick for ev in e.events_query(e.placeholder_event()["a"] == 1)] == [10] assert_raises(ValueError, e.events_query, []) e2 = Events() assert_raises(ValueError, e.events_query, e2.events_query(True))
def test_misc_queries(): # ANY, at, __iter__, __len__ e = Events() r = MockRecording() e.add_event(r, 0, 20, 21, {"a": -1}) e.add_event(r, 0, 10, 11, {"a": 1}) e.add_event(r, 0, 30, 31, {"a": 100}) assert len(e) == 3 # Always sorted by index: assert [ev.start_idx for ev in e] == [10, 20, 30] assert [ev.start_idx for ev in e.find(e.ANY)] == [10, 20, 30] assert len(e.at(r, 0, 10)) == 1 assert e.at(r, 0, 10)[0]["a"] == 1 assert len(e.at(r, 0, 20)) == 1 assert e.at(r, 0, 20)[0]["a"] == -1 assert len(e.at(r, 0, 15)) == 0 assert len(e.at(r, 0, 15, 40)) == 2
def load_eeglab(set_filename, dtype=np.float64): # Read the .mat file contents = loadmat(set_filename) if "EEG" not in contents: if "ALLEEG" in contents: raise EEGLABError("reading of multi-set files is not implemented " " -- patches gratefully accepted") else: raise EEGLABError("no 'EEG' variable found in matlab file") EEG = contents["EEG"][0, 0] srate = EEG["srate"][0, 0] units = "??" electrodes = extract_electrode_info(EEG) # General metadata: metadata = {} for key in ["setname", "filename", "filepath", "comments", "etc", "subject", "group", "condition", "session", "ref", "icasphere", "icaweights", "icawinv"]: if key in EEG.dtype.names and EEG[key].size > 0: if np.issubdtype(EEG[key], np.character_): metadata[key] = EEG[key][0] else: metadata[key] = EEG[key] recording_info = RecordingInfo(srate, units, electrodes, metadata) data = extract_data_matrix(EEG, set_filename, dtype) data = data.T (num_epochs, num_channels, num_samples) = data.shape if num_epochs != 1: raise EEGLABError("reading of epoched data is not implemented " " -- patches gratefully accepted") assert num_epochs == 1 data.resize(data.shape[1:]) # Events # type (string) and latency (int) are the main ones # type == "boundary" is special # duration is length of removed data if data was removed (generally 0, # or NaN for breaks between concatenated datasets) # usually only for type == "boundary" # "latency" is a floating point number, which refers to a 1-based index in # the data array. It's floating point because for some events, like # "boundary" events, they actually place the event *in between* two frames # -- so if you have two data sets # [10, 11, 12] # and # [17, 18, 19] # then the concatenated set is # [10, 11, 12, 17, 18, 19] # with the 'latency' of the boundary event set to 3.5. zero_based_boundaries = [] for eeglab_event in EEG["event"].ravel(): if eeglab_event["type"].item() == "boundary": zero_based_boundaries.append(eeglab_event["latency"] - 1) name_index = [metadata["setname"]] * num_samples era_index = np.empty(num_samples, dtype=int) #time_index = np.empty(num_samples, dtype= ev = Events((str, int, int)) if num_epochs == 1: # Continuous data # XX pass else: # Epoched data # EEG.xmin, EEG.xmax = start/end latency of epoch in seconds # EEG.epoch == ? # XX pass
def test_misc_queries(): # ANY, at, __iter__, __len__ e = Events() e.add_recspan_info(0, 100, {}) e.add_recspan_info(1, 100, {}) e.add_event(0, 20, 21, {"a": -1}) e.add_event(0, 10, 11, {"a": 1}) e.add_event(0, 30, 31, {"a": 100}) e.add_event(1, 15, 16, {}) assert len(e.events_query(True)) == 4 # Always sorted by index: assert [ev.start_tick for ev in e.events_query(True)] == [10, 20, 30, 15]
def test_string_query(): e = Events() r1 = MockRecording("r1") r2 = MockRecording("r2") e.add_event(r1, 0, 10, 12, { "a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None }) e.add_event( r2, 1, 20, 25, { "a": 2, "b": "fdsa", "c": False, "d": 5.1, "e": 22, "f": "stuff", "_RECORDING_NAME": "r100", "_START_IDX": 10, "and": 33 }) def t(s, expected_start_indices): result = e.find(s) start_indices = [ev.start_idx for ev in result] assert start_indices == expected_start_indices # all operators t("a == 2", [20]) t("a != 2", [10]) t("a < 2", [10]) t("a > 1", [20]) t("a <= 2", [10, 20]) t("a >= 1", [10, 20]) t("not (a > 1)", [10]) t("c", [10]) t("not c", [20]) t("has f", [20]) t("a == 1 and d > 1", [10]) t("a == 1 and d > 2", []) t("a == 1 or d > 2", [10, 20]) t("1 == 1", [10, 20]) # quoting t("b == \"asdf\"", [10]) t("b == \'asdf\'", [10]) t("`a` == 1", [10]) assert_raises(EventsError, e.find, "a == \"1\"") # RECORDING_NAME and friends t("_RECORDING_NAME == 'r1'", [10]) t("_RECORDING_NAME == 'r2'", [20]) t("_SPAN_ID == 1", [20]) t("_START_IDX < 15", [10]) t("_STOP_IDX > 22", [20]) # backquotes t("has `_RECORDING_NAME`", [20]) t("`_RECORDING_NAME` == 'r100'", [20]) t("`_START_IDX` == 10", [20]) t("`and` == 33", [20]) t("not has `and`", [10])
def test_python_query(): # all operators # types (esp. including None) # index e = Events() e.add_recspan_info(0, 100, {"recspan_zero": True}) e.add_recspan_info(1, 100, {"recspan_zero": False, "recspan_extra": "hi"}) ev10 = e.add_event(0, 10, 11, {"a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None}) ev20 = e.add_event(1, 20, 25, {"a": -1, "b": "fdsa", "c": False, "d": -3.14, "e": None}) ev21 = e.add_event(0, 21, 26, {"a": 1, "b": "asdf", "c": False, "d": -3.14, "e": 123}) p = e.placeholder_event() def t(q, expected): assert [ev.start_tick for ev in q] == expected assert_raises(TypeError, lambda q: not q, e.events_query(True)) assert_raises(EventsError, p.start_tick.__eq__, []) t(p.start_tick == 10, [10]) t(p.start_tick != 10, [21, 20]) t(p.start_tick < 10, []) t(p.start_tick > 10, [21, 20]) t(p.start_tick >= 20, [21, 20]) t(p.start_tick <= 20, [10, 20]) t(~(p.start_tick == 20), [10, 21]) t(~(p.start_tick != 20), [20]) t(p["a"] == 1, [10, 21]) t(p["a"] != 1, [20]) t(p["a"] < 1, [20]) t(p["a"] > 1, []) t(p["a"] >= 1, [10, 21]) t(p["a"] <= 1, [10, 21, 20]) t(~(p["a"] == 1), [20]) t(~(p["a"] != 1), [10, 21]) t(p["a"] == 1.5, []) t(p["a"] < 1.5, [10, 21, 20]) t(p["a"] < 0.5, [20]) t(p["a"] > 0.5, [10, 21]) t(p["b"] == "asdf", [10, 21]) t(p["b"] != "asdf", [20]) t(p["b"] < "asdf", []) t(p["b"] > "asdf", [20]) t(p["b"] >= "asdf", [10, 21, 20]) t(p["b"] <= "asdf", [10, 21]) t(p["b"] <= "b", [10, 21]) t(p["b"] >= "b", [20]) t(~(p["b"] == "asdf"), [20]) t(~(p["b"] != "asdf"), [10, 21]) t(p["c"] == True, [10]) t(p["c"] != True, [21, 20]) t(p["c"] == False, [21, 20]) t(p["c"] != False, [10]) t(p["c"], [10]) t(~p["c"], [21, 20]) t(p["c"] < True, [21, 20]) t(p["c"] <= True, [10, 21, 20]) t(p["c"] > True, []) t(p["c"] > False, [10]) t(p["c"] >= False, [10, 21, 20]) t(~(p["c"] == True), [21, 20]) t(~(p["c"] != True), [10]) t(p["d"] == 1.5, [10]) t(p["d"] != 1.5, [21, 20]) t(p["d"] < 1.5, [21, 20]) t(p["d"] > 1.5, []) t(p["d"] >= 1.5, [10]) t(p["d"] <= 1.5, [10, 21, 20]) t(~(p["d"] == 1.5), [21, 20]) t(~(p["d"] != 1.5), [10]) t(p["d"] == 1, []) t(p["d"] < 10, [10, 21, 20]) t(p["d"] < 1, [21, 20]) t(p["d"] > 1, [10]) t(p["e"] == None, [10, 20]) t(p["e"] != None, [21]) t(p.has_key("e"), [10, 21, 20]) t(~p.has_key("e"), []) t(p["nonexistent"] == 10, []) t(p["nonexistent"] != 10, []) t(p["nonexistent"] == None, []) t(p["nonexistent"].exists(), []) t(p.has_key("nonexistent"), []) t(~p["nonexistent"].exists(), [10, 21, 20]) t(~p.has_key("nonexistent"), [10, 21, 20]) t(p["a"] > p["d"], [21, 20]) t(p["a"] < p["d"], [10]) t((p.start_tick < 21) & (p["a"] == 1), [10]) t((p.start_tick < 21) | (p["a"] == 1), [10, 21, 20]) t(~((p.start_tick < 21) & (p["a"] == 1)), [21, 20]) t(~((p.start_tick < 21) | (p["a"] == 1)), []) t(p.stop_tick == 26, [21]) t(p.overlaps(ev10), [10]) t(p.overlaps(ev20), [20]) t(p.overlaps(ev21), [21]) t(p.overlaps(0, 5, 10), []) t(p.overlaps(0, 5, 11), [10]) t(p.overlaps(0, 11, 20), []) t(p.overlaps(0, 11, 100), [21]) for i in xrange(20, 25): t(p.overlaps(1, i, i + 1), [20]) assert_raises(ValueError, p.overlaps, p) t(p.recspan_info["recspan_zero"], [10, 21]) t(~p.recspan_info["recspan_zero"], [20]) t(p.recspan_info["recspan_extra"].exists(), [20])
def test_string_query(): e = Events() e.add_recspan_info(0, 100, {"recspan_attr1": 33}) e.add_recspan_info(1, 100, {"recspan_attr2": "hello"}) e.add_event(0, 10, 12, {"a": 1, "b": "asdf", "c": True, "d": 1.5, "e": None, "backslash": "nope"}) e.add_event(1, 20, 25, {"a": 2, "b": "fdsa", "c": False, "d": 5.1, "e": 22, "f": "stuff", "_START_TICK": 10, "and": 33, "backslash": "\\"}) def t(s, expected_start_indices): start_indices = [ev.start_tick for ev in e.events_query(s)] assert start_indices == expected_start_indices # all operators t("a == 2", [20]) t("a != 2", [10]) t("a < 2", [10]) t("a > 1", [20]) t("a <= 2", [10, 20]) t("a >= 1", [10, 20]) t("not (a > 1)", [10]) t("c", [10]) t("not c", [20]) t("has f", [20]) assert_raises(EventsError, e.events_query, "has \"asdf\"") t("a == 1 and d > 1", [10]) t("a == 1 and d > 2", []) t("a == 1 or d > 2", [10, 20]) t("1 == 1", [10, 20]) # floats t("d == 5.1", [20]) t("d == 51e-1", [20]) t("d > -1e2", [10, 20]) # none (case-insensitive) t("e == NoNe", [10]) # bools (case-insensitive) t("c == tRUe", [10]) t("c == FAlsE", [20]) # quoting t("b == \"asdf\"", [10]) t("b == \'asdf\'", [10]) t("`a` == 1", [10]) assert_raises(EventsError, e.events_query, "a == \"1\"") t(r"backslash == '\\'", [20]) assert_raises(EventsError, e.events_query, "a == \"trailing") assert_raises(EventsError, e.events_query, "a == \"bad escape\\n\"") assert_raises(EventsError, e.events_query, "a == \"trailing escape\\") # _RECSPAN_ID and friends t("_RECSPAN_ID == 1", [20]) t("_START_TICK < 15", [10]) t("_STOP_TICK > 22", [20]) t("_RECSPAN_INFO.recspan_attr1 == 20", []) t("has _RECSPAN_INFO.recspan_attr1", [10]) assert_raises(EventsError, e.events_query, "foo.bar == 1") assert_raises(EventsError, e.events_query, "_RECSPAN_INFO == 1") assert_raises(EventsError, e.events_query, "_RECSPAN_INFO._RECSPAN_INFO == 1") assert_raises(EventsError, e.events_query, "_RECSPAN_INFO.\"asdf\" == 1") # backquotes t("`_START_TICK` == 10", [20]) t("`and` == 33", [20]) t("not has `and`", [10])
def test_Event(): # set/get/del, index # dict methods e = Events() r1 = e.add_recspan_info(1, 100, {}) d = {"a": 1, "b": "hello", "c": True} ev1 = e.add_event(1, 10, 12, d) assert ev1.recspan_id == 1 assert ev1.start_tick == 10 assert ev1.stop_tick == 12 assert dict(ev1.iteritems()) == d ev1["added"] = True assert ev1["added"] == True assert_raises(KeyError, ev1.__getitem__, "notadded") assert_raises(KeyError, ev1.__delitem__, "notadded") del ev1["added"] assert_raises(KeyError, ev1.__getitem__, "added") assert_raises(KeyError, ev1.__delitem__, "added") assert "a" in ev1 assert "added" not in ev1 assert_raises(ValueError, ev1.__setitem__, "c", "asdf") assert ev1["c"] == True assert ev1.get("c") == True assert ev1.get("notadded") is None assert ev1.get("notadded", 10) == 10 assert sorted(list(ev1)) == ["a", "b", "c"] assert sorted(ev1.iterkeys()) == ["a", "b", "c"] assert sorted(ev1.itervalues()) == sorted(d.itervalues()) assert list(ev1.iterkeys()) == ev1.keys() assert list(ev1.itervalues()) == ev1.values() assert list(ev1.iteritems()) == ev1.items() assert ev1.has_key("a") assert not ev1.has_key("z") assert ev1.overlaps(ev1) assert not ev1.overlaps(0, 9, 11) assert ev1.overlaps(1, 9, 11) assert ev1.overlaps(1, 10, 12) assert ev1.overlaps(1, 10, 11) assert ev1.overlaps(1, 11, 12) assert not ev1.overlaps(1, 0, 2) assert not ev1.overlaps(1, 100, 102) # Check half-openness assert not ev1.overlaps(0, 9, 10) assert not ev1.overlaps(0, 12, 15) # Nothing overlaps an empty interval assert not ev1.overlaps(0, 11, 11) # Check .update ev1.update({"new1": "asdf", "new2": 3.14}) assert ev1["new1"] == "asdf" assert ev1["new2"] == 3.14 # smoke test repr(ev1) assert len(e.events_query(True)) == 1 ev1.delete() assert len(e.events_query(True)) == 0 # XX: maybe this should be a ValueError or something, but checking for # whether the event object itself exists in __getitem__ is extra work that # doesn't seem worth bothering with. assert_raises(KeyError, ev1.__getitem__, "a") assert_raises(EventsError, ev1.__setitem__, "a", 1) # smoke test for deleted one repr(ev1)
def test_Events_basic(): # load/store of different types # errors on type mismatches # storing None e = Events() # need a recspan before adding events assert_raises(EventsError, e.add_event, 0, 10, 11, {}) r1 = e.add_recspan_info(0, 100, {"a": "hello", "b": True, "c": None, "d": 1}) assert r1.id == 0 assert r1.ticks == 100 assert r1["a"] == "hello" assert r1["b"] == True assert r1["c"] is None assert r1["d"] is 1 # Use same names, different types, to check that type constraints don't # apply between events and recspans ev1 = e.add_event(0, 10, 11, {"a": 1, "b": "hello", "c": True, "d": 1.5}) assert ev1.recspan_id == 0 assert ev1.start_tick == 10 assert ev1.stop_tick == 11 assert ev1.recspan_info.id == 0 assert ev1.recspan_info == r1 assert ev1["a"] == 1 assert ev1["b"] == "hello" assert ev1["c"] == True assert ev1["d"] == 1.5 assert type(ev1["a"]) == int assert type(ev1["b"]) == str assert type(ev1["c"]) == bool assert type(ev1["d"]) == float assert dict(ev1) == {"a": 1, "b": "hello", "c": True, "d": 1.5} ev1["a"] = 2 assert ev1["a"] == 2 assert_raises(ValueError, e.add_event, 0, 20, 21, {"a": "string"}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"a": True}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"b": 10}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"b": True}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"c": 10}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"c": "string"}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"asdf": []}) ev1["a"] = None assert ev1["a"] is None ev1["xxx"] = None ev2 = e.add_event(0, 11, 12, {"xxx": 3}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"xxx": "string"}) assert_raises(ValueError, e.add_event, 0, 20, 21, {"xxx": True}) assert ev2["xxx"] == 3 assert ev2.start_tick == 11 assert ev1["xxx"] is None assert_raises(ValueError, cPickle.dumps, r1) assert_raises(ValueError, cPickle.dumps, ev1) e_pick = cPickle.loads(cPickle.dumps(e)) r1_pick, = e_pick._all_recspan_infos() assert r1_pick.id == 0 assert r1_pick.ticks == 100 assert r1_pick.items() == r1.items() ev1_pick, ev2_pick = list(e_pick.events_query(True)) assert ev1_pick.recspan_id == 0 assert ev1_pick.start_tick == 10 assert ev1_pick.stop_tick == 11 assert sorted(ev1_pick.items()) == sorted(ev1.items()) assert ev2_pick.recspan_id == 0 assert ev2_pick.start_tick == 11 assert ev2_pick.stop_tick == 12 assert sorted(ev2_pick.items()) == sorted(ev2.items()) assert_raises(ValueError, e.add_event, 0, 20, 20, {}) assert_raises(ValueError, e.add_event, 0, 20, 19, {}) assert_raises(ValueError, e.add_event, 0, -10, 10, {})