Пример #1
0
    def test_dataselection(self):
        dummy = AnalogData(data=self.data,
                           trialdefinition=self.trl,
                           samplerate=self.samplerate)
        trialSelections = [
            "all",  # enforce below selections in all trials of `dummy`
            [3, 1]  # minimally unordered
        ]
        chanSelections = [
            ["channel03", "channel01", "channel01",
             "channel02"],  # string selection w/repetition + unordered
            [4, 2, 2, 5, 5],  # repetition + unorderd
            range(5, 8),  # narrow range
            slice(-2, None)  # negative-start slice
        ]
        toiSelections = [
            "all",  # non-type-conform string
            [0.6],  # single inexact match
            [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
             3.]  # unordered, inexact, repetions
        ]
        toilimSelections = [
            [0.5, 1.5],  # regular range
            [1.5, 2.0],  # minimal range (just two-time points)
            [1.0, np.inf]  # unbounded from above
        ]
        timeSelections = list(zip(["toi"] * len(toiSelections), toiSelections)) \
            + list(zip(["toilim"] * len(toilimSelections), toilimSelections))

        idx = [slice(None)] * len(dummy.dimord)
        timeIdx = dummy.dimord.index("time")
        chanIdx = dummy.dimord.index("channel")

        for trialSel in trialSelections:
            for chanSel in chanSelections:
                for timeSel in timeSelections:
                    kwdict = {}
                    kwdict["trials"] = trialSel
                    kwdict["channels"] = chanSel
                    kwdict[timeSel[0]] = timeSel[1]
                    cfg = StructDict(kwdict)
                    # data selection via class-method + `Selector` instance for indexing
                    selected = dummy.selectdata(**kwdict)
                    selector = Selector(dummy, kwdict)
                    idx[chanIdx] = selector.channel
                    for tk, trialno in enumerate(selector.trials):
                        idx[timeIdx] = selector.time[tk]
                        assert np.array_equal(
                            selected.trials[tk].squeeze(),
                            dummy.trials[trialno][idx[0], :][:,
                                                             idx[1]].squeeze())
                    cfg.data = dummy
                    cfg.out = AnalogData(dimord=AnalogData._defaultDimord)
                    # data selection via package function and `cfg`: ensure equality
                    selectdata(cfg)
                    assert np.array_equal(cfg.out.channel, selected.channel)
                    assert np.array_equal(cfg.out.data, selected.data)
Пример #2
0
    def test_dataselection(self):
        dummy = EventData(data=self.data,
                          trialdefinition=self.trl,
                          samplerate=2.0)
        # selections are chosen so that result is not empty
        trialSelections = [
            "all",  # enforce below selections in all trials of `dummy`
            [3, 1]  # minimally unordered
        ]
        eventidSelections = [
            [0, 0, 1],  # preserve repetition, don't convert to slice
            range(0, 2),  # narrow range
            slice(-2, None)  # negative-start slice
        ]
        toiSelections = [
            "all",  # non-type-conform string
            [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
             3.]  # unordered, inexact, repetions
        ]
        toilimSelections = [
            [0.5, 3.5],  # regular range
            [0.0, np.inf]  # unbounded from above
        ]
        timeSelections = list(zip(["toi"] * len(toiSelections), toiSelections)) \
            + list(zip(["toilim"] * len(toilimSelections), toilimSelections))

        eventidIdx = dummy.dimord.index("eventid")

        for trialSel in trialSelections:
            for eventidSel in eventidSelections:
                for timeSel in timeSelections:
                    kwdict = {}
                    kwdict["trials"] = trialSel
                    kwdict["eventids"] = eventidSel
                    kwdict[timeSel[0]] = timeSel[1]
                    cfg = StructDict(kwdict)
                    # data selection via class-method + `Selector` instance for indexing
                    selected = dummy.selectdata(**kwdict)
                    selector = Selector(dummy, kwdict)
                    tk = 0
                    for trialno in selector.trials:
                        if selector.time[tk]:
                            assert np.array_equal(
                                dummy.trials[trialno][selector.time[tk], :],
                                selected.trials[tk])
                            tk += 1
                    assert np.array_equal(
                        selected.eventid, dummy.eventid[np.unique(
                            selected.data[:, eventidIdx]).astype(np.intp)])
                    cfg.data = dummy
                    cfg.out = EventData(dimord=EventData._defaultDimord)
                    # data selection via package function and `cfg`: ensure equality
                    selectdata(cfg)
                    assert np.array_equal(cfg.out.eventid, selected.eventid)
                    assert np.array_equal(cfg.out.data, selected.data)
Пример #3
0
    def test_dataselection(self):
        dummy = SpikeData(data=self.data,
                          trialdefinition=self.trl,
                          samplerate=2.0)
        # selections are chosen so that result is not empty
        trialSelections = [
            "all",  # enforce below selections in all trials of `dummy`
            [3, 1]  # minimally unordered
        ]
        chanSelections = [
            ["channel03", "channel01", "channel01",
             "channel02"],  # string selection w/repetition + unordered
            [4, 2, 2, 5, 5],  # repetition + unorderd
            range(5, 8),  # narrow range
            slice(-5, None)  # negative-start slice
        ]
        toiSelections = [
            "all",  # non-type-conform string
            [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
             3.]  # unordered, inexact, repetions
        ]
        toilimSelections = [
            [0.5, 3.5],  # regular range
            [1.0, np.inf]  # unbounded from above
        ]
        unitSelections = [
            ["unit1", "unit1", "unit2", "unit3"],  # preserve repetition
            [0, 0, 2, 3],  # preserve repetition, don't convert to slice
            range(1, 4),  # narrow range
            slice(-2, None)  # negative-start slice
        ]
        timeSelections = list(zip(["toi"] * len(toiSelections), toiSelections)) \
            + list(zip(["toilim"] * len(toilimSelections), toilimSelections))

        chanIdx = dummy.dimord.index("channel")
        unitIdx = dummy.dimord.index("unit")
        chanArr = np.arange(dummy.channel.size)

        for trialSel in trialSelections:
            for chanSel in chanSelections:
                for unitSel in unitSelections:
                    for timeSel in timeSelections:
                        kwdict = {}
                        kwdict["trials"] = trialSel
                        kwdict["channels"] = chanSel
                        kwdict["units"] = unitSel
                        kwdict[timeSel[0]] = timeSel[1]
                        cfg = StructDict(kwdict)
                        # data selection via class-method + `Selector` instance for indexing
                        selected = dummy.selectdata(**kwdict)
                        selector = Selector(dummy, kwdict)
                        tk = 0
                        for trialno in selector.trials:
                            if selector.time[tk]:
                                assert np.array_equal(
                                    dummy.trials[trialno][
                                        selector.time[tk], :],
                                    selected.trials[tk])
                                tk += 1
                        assert set(selected.data[:, chanIdx]).issubset(
                            chanArr[selector.channel])
                        assert set(selected.channel) == set(
                            dummy.channel[selector.channel])
                        assert np.array_equal(
                            selected.unit,
                            dummy.unit[np.unique(selected.data[:, unitIdx])])
                        cfg.data = dummy
                        cfg.out = SpikeData(dimord=SpikeData._defaultDimord)
                        # data selection via package function and `cfg`: ensure equality
                        selectdata(cfg)
                        assert np.array_equal(cfg.out.channel,
                                              selected.channel)
                        assert np.array_equal(cfg.out.unit, selected.unit)
                        assert np.array_equal(cfg.out.data, selected.data)
Пример #4
0
    def test_spectral_foifoilim(self):

        # this selection only works w/the dummy frequency data constructed above!!!
        selDict = {
            "foi": (
                None,  # trivial "selection" of entire contents,
                "all",  # trivial "selection" of entire contents
                [1],  # single entry lists
                [2.6],  # inexact match
                [2, 9],  # two disjoint frequencies
                [7.2, 8.3],  # inexact from above
                [6.8, 11.9],  # inexact from below
                [0.4, 13.1],  # inexact from below, inexact from above
                [1.2, 2.9],  # inexact from above, inexact from below
                [1.1, 1.9, 2.1, 3.9, 9.2, 11.8, 12.9, 5.1,
                 13.8],  # alternating madness
                [2, 1, 11],  # unsorted list
                [5, 2, 2, 3],  # repetition
                [1, 1, 2, 3],  # preserve repetition, don't convert to slice
                [2, 3,
                 4]),  # sorted list (should be converted to slice-selection)
            "foilim": (
                None,  # trivial "selection" of entire contents,
                "all",  # trivial "selection" of entire contents
                [2, 11],  # regular range
                [1, 2],  # minimal range (just two-time points)
                [1.0, np.inf],  # unbounded from above
                [-np.inf, 12])
        }  # unbounded from below

        spc = SpectralData(data=self.data['SpectralData'],
                           trialdefinition=self.trl['SpectralData'],
                           samplerate=self.samplerate)
        allFreqs = spc.freq
        spcIdx = [slice(None)] * len(spc.dimord)
        freqIdx = spc.dimord.index("freq")

        for fselect in ["foi", "foilim"]:
            for freqSel in selDict[fselect]:
                sel = Selector(spc, {fselect: freqSel}).freq
                if freqSel is None or freqSel == "all":
                    idx = slice(None)
                else:
                    if fselect == "foi":
                        idx = []
                        for fq in freqSel:
                            idx.append(np.abs(allFreqs - fq).argmin())
                    else:
                        idx = np.intersect1d(
                            np.where(allFreqs >= freqSel[0])[0],
                            np.where(allFreqs <= freqSel[1])[0])

                # check that correct data was selected (all trials identical, just take 1st one)
                assert np.array_equal(spc.freq[idx], spc.freq[sel])
                if not isinstance(idx, slice) and len(idx) > 1:
                    freqSteps = np.diff(idx)
                    if freqSteps.min() == freqSteps.max() == 1:
                        idx = slice(idx[0], idx[-1] + 1, 1)

                # check correct format of selector (list -> slice etc.)
                assert np.array_equal(idx, sel)

                # perform actual data-selection and ensure identity of results
                selected = selectdata(spc, {fselect: freqSel})
                spcIdx[freqIdx] = idx
                assert np.array_equal(selected.freq, spc.freq[sel])
                for trialno in range(len(spc.trials)):
                    assert np.array_equal(selected.trials[trialno],
                                          spc.trials[trialno][tuple(spcIdx)])
Пример #5
0
    def test_discrete_toitoilim(self):

        # this only works w/the equidistant trials constructed above!!!
        selDict = {
            "toi": (
                None,  # trivial "selection" of entire contents
                "all",  # trivial "selection" of entire contents
                [0.5],  # single entry lists
                [0.6],  # inexact match
                [1.0, 2.5],  # two disjoint time-points
                [1.2, 2.7],  # inexact from above
                [1.9, 2.4],  # inexact from below
                [0.4, 2.1],  # inexact from below, inexact from above
                [1.6, 1.9],  # inexact from above, inexact from below
                [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
                 3.],  # alternating madness
                [2.0, 0.5, 2.5],  # unsorted list
                [1.0, 0.5, 0.5, 1.5],  # repetition
                [0.5, 0.5, 1.0,
                 1.5],  # preserve repetition, don't convert to slice
                [0.5, 1.0,
                 1.5]),  # sorted list (should be converted to slice-selection)
            "toilim": (
                None,  # trivial "selection" of entire contents
                "all",  # trivial "selection" of entire contents
                [0.5, 1.5],  # regular range
                [1.5, 2.0],  # minimal range (just two-time points)
                [1.0, np.inf],  # unbounded from above
                [-np.inf, 1.0])
        }  # unbounded from below

        # all trials have same time-scale for both `EventData` and `SpikeData`: take 1st one as reference
        trlTime = list((np.arange(
            0, self.trl["SpikeData"][0, 1] - self.trl["SpikeData"][0, 0]) +
                        self.trl["SpikeData"][0, 2]) / 2)

        # the below method of extracting spikes satisfying `toi`/`toilim` only works w/equidistant trials!
        for dclass in ["SpikeData", "EventData"]:
            discrete = getattr(spd, dclass)(data=self.data[dclass],
                                            trialdefinition=self.trl[dclass],
                                            samplerate=self.samplerate)
            for tselect in ["toi", "toilim"]:
                for timeSel in selDict[tselect]:
                    if isinstance(timeSel, list):
                        smpIdx = []
                        for tp in timeSel:
                            if np.isfinite(tp):
                                smpIdx.append(
                                    np.abs(np.array(trlTime) - tp).argmin())
                            else:
                                smpIdx.append(tp)
                    result = []
                    sel = Selector(discrete, {tselect: timeSel}).time
                    selected = selectdata(discrete, {tselect: timeSel})
                    tk = 0
                    for trlno in range(len(discrete.trials)):
                        thisTrial = discrete.trials[trlno][:, 0]
                        if isinstance(timeSel, list):
                            if tselect == "toi":
                                trlRes = []
                                for idx in smpIdx:
                                    trlRes += list(
                                        np.where(thisTrial == idx +
                                                 trlno * self.lenTrial)[0])
                            else:
                                start = smpIdx[0] + trlno * self.lenTrial
                                stop = smpIdx[1] + trlno * self.lenTrial
                                candidates = np.intersect1d(
                                    thisTrial[thisTrial >= start],
                                    thisTrial[thisTrial <= stop])
                                trlRes = []
                                for cand in candidates:
                                    trlRes += list(
                                        np.where(thisTrial == cand)[0])
                        else:
                            trlRes = slice(0, thisTrial.size, 1)

                        # ensure that actually selected data is correct
                        assert np.array_equal(
                            discrete.trials[trlno][trlRes, :],
                            discrete.trials[trlno][sel[trlno], :])
                        if sel[trlno]:
                            assert np.array_equal(
                                selected.trials[tk],
                                discrete.trials[trlno][sel[trlno], :])
                            tk += 1

                        if not isinstance(trlRes, slice) and len(trlRes) > 1:
                            sampSteps = np.diff(trlRes)
                            if sampSteps.min() == sampSteps.max() == 1:
                                trlRes = slice(trlRes[0], trlRes[-1] + 1, 1)
                        result.append(trlRes)

                    # check correct format of selector (list -> slice etc.)
                    assert result == sel
Пример #6
0
    def test_continuous_toitoilim(self):

        # this only works w/the equidistant trials constructed above!!!
        selDict = {
            "toi": (
                None,  # trivial "selection" of entire contents
                "all",  # trivial "selection" of entire contents
                [0.5],  # single entry lists
                [0.6],  # inexact match
                [1.0, 2.5],  # two disjoint time-points
                [1.2, 2.7],  # inexact from above
                [1.9, 2.4],  # inexact from below
                [0.4, 2.1],  # inexact from below, inexact from above
                [1.6, 1.9],  # inexact from above, inexact from below
                [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
                 3.],  # alternating madness
                [2.0, 0.5, 2.5],  # unsorted list
                [1.0, 0.5, 0.5, 1.5],  # repetition
                [0.5, 0.5, 1.0,
                 1.5],  # preserve repetition, don't convert to slice
                [0.5, 1.0,
                 1.5]),  # sorted list (should be converted to slice-selection)
            "toilim": (
                None,  # trivial "selection" of entire contents
                "all",  # trivial "selection" of entire contents
                [0.5, 1.5],  # regular range
                [1.5, 2.0],  # minimal range (just two-time points)
                [1.0, np.inf],  # unbounded from above
                [-np.inf, 1.0])
        }  # unbounded from below

        # all trials have same time-scale: take 1st one as reference
        trlTime = (np.arange(
            0, self.trl["AnalogData"][0, 1] - self.trl["AnalogData"][0, 0]) +
                   self.trl["AnalogData"][0, 2]) / self.samplerate

        ang = AnalogData(data=self.data["AnalogData"],
                         trialdefinition=self.trl["AnalogData"],
                         samplerate=self.samplerate)
        angIdx = [slice(None)] * len(ang.dimord)
        timeIdx = ang.dimord.index("time")

        # the below check only works for equidistant trials!
        for tselect in ["toi", "toilim"]:
            for timeSel in selDict[tselect]:
                sel = Selector(ang, {tselect: timeSel}).time
                if timeSel is None or timeSel == "all":
                    idx = slice(None)
                else:
                    if tselect == "toi":
                        idx = []
                        for tp in timeSel:
                            idx.append(np.abs(trlTime - tp).argmin())
                    else:
                        idx = np.intersect1d(
                            np.where(trlTime >= timeSel[0])[0],
                            np.where(trlTime <= timeSel[1])[0])

                # check that correct data was selected (all trials identical, just take 1st one)
                assert np.array_equal(ang.trials[0][idx, :],
                                      ang.trials[0][sel[0], :])
                if not isinstance(idx, slice) and len(idx) > 1:
                    timeSteps = np.diff(idx)
                    if timeSteps.min() == timeSteps.max() == 1:
                        idx = slice(idx[0], idx[-1] + 1, 1)
                result = [idx] * len(ang.trials)

                # check correct format of selector (list -> slice etc.)
                assert np.array_equal(result, sel)

                # perform actual data-selection and ensure identity of results
                selected = selectdata(ang, {tselect: timeSel})
                for trialno in range(len(ang.trials)):
                    angIdx[timeIdx] = result[trialno]
                    assert np.array_equal(selected.trials[trialno],
                                          ang.trials[trialno][tuple(angIdx)])
Пример #7
0
    def test_general(self):

        # construct expected results for `DiscreteData` objects defined above
        mapDict = {"unit": "SpikeData", "eventid": "EventData"}
        for prop, dclass in mapDict.items():
            discrete = getattr(spd, dclass)(data=self.data[dclass],
                                            trialdefinition=self.trl[dclass],
                                            samplerate=self.samplerate)
            propIdx = discrete.dimord.index(prop)

            # convert selection from `selectDict` to a usable integer-list
            allResults = []
            for selection in self.selectDict[prop]["valid"]:
                if isinstance(selection, slice):
                    if selection.start is selection.stop is None:
                        selects = [None]
                    else:
                        selects = list(range(getattr(discrete,
                                                     prop).size))[selection]
                elif isinstance(selection, range):
                    selects = list(selection)
                elif isinstance(selection, str) or selection is None:
                    selects = [None]
                else:  # selection is list/ndarray
                    if isinstance(selection[0], str):
                        avail = getattr(discrete, prop)
                    else:
                        avail = np.arange(getattr(discrete, prop).size)
                    selects = []
                    for sel in selection:
                        selects += list(np.where(avail == sel)[0])

                # alternate (expensive) way to get by-trial selection indices
                result = []
                for trial in discrete.trials:
                    if selects[0] is None:
                        res = slice(0, trial.shape[0], 1)
                    else:
                        res = []
                        for sel in selects:
                            res += list(np.where(trial[:, propIdx] == sel)[0])
                        if len(res) > 1:
                            steps = np.diff(res)
                            if steps.min() == steps.max() == 1:
                                res = slice(res[0], res[-1] + 1, 1)
                    result.append(res)
                allResults.append(result)

            self.selectDict[prop]["result"] = tuple(allResults)

        # wrong type of data and/or selector
        with pytest.raises(SPYTypeError):
            Selector(np.empty((3, )), {})
        with pytest.raises(SPYValueError):
            Selector(spd.AnalogData(), {})
        ang = AnalogData(data=self.data["AnalogData"],
                         trialdefinition=self.trl["AnalogData"],
                         samplerate=self.samplerate)
        with pytest.raises(SPYTypeError):
            Selector(ang, ())
        with pytest.raises(SPYValueError):
            Selector(ang, {"wrongkey": [1]})

        # go through all data-classes defined above
        for dclass in self.classes:
            dummy = getattr(spd, dclass)(data=self.data[dclass],
                                         trialdefinition=self.trl[dclass],
                                         samplerate=self.samplerate)

            # test trial selection
            selection = Selector(dummy, {"trials": [3, 1]})
            assert selection.trials == [3, 1]
            selected = selectdata(dummy, trials=[3, 1])
            assert np.array_equal(selected.trials[0], dummy.trials[3])
            assert np.array_equal(selected.trials[1], dummy.trials[1])
            assert selected.trialdefinition.shape == (2, 4)
            assert np.array_equal(selected.trialdefinition[:, -1],
                                  dummy.trialdefinition[[3, 1], -1])

            for trlSec in [None, "all"]:
                selection = Selector(dummy, {"trials": trlSec})
                assert selection.trials == list(range(len(dummy.trials)))
                selected = selectdata(dummy, trials=trlSec)
                for tk, trl in enumerate(selected.trials):
                    assert np.array_equal(trl, dummy.trials[tk])
                assert np.array_equal(selected.trialdefinition,
                                      dummy.trialdefinition)

            with pytest.raises(SPYValueError):
                Selector(dummy, {"trials": [-1, 9]})

            # test "simple" property setters handled by `_selection_setter`
            # for prop in ["eventid"]:
            for prop in ["channel", "taper", "unit", "eventid"]:
                if hasattr(dummy, prop):
                    expected = self.selectDict[prop]["result"]
                    for sk, sel in enumerate(self.selectDict[prop]["valid"]):
                        solution = expected[sk]
                        if dclass == "SpikeData" and prop == "channel":
                            if isinstance(solution, slice):
                                start, stop, step = solution.start, solution.stop, solution.step
                                if start is None:
                                    start = 0
                                elif start < 0:
                                    start = len(dummy.channel) + start
                                if stop is None:
                                    stop = len(dummy.channel)
                                elif stop < 0:
                                    stop = len(dummy.channel) + stop
                                if step not in [None, 1]:
                                    solution = list(range(start,
                                                          stop))[solution]
                                else:
                                    solution = slice(start, stop, step)

                        # once we're sure `Selector` works, actually select data
                        selection = Selector(dummy, {prop + "s": sel})
                        assert getattr(selection, prop) == solution
                        selected = selectdata(dummy, {prop + "s": sel})

                        # process `unit` and `enventid`
                        if prop in selection._byTrialProps:
                            propIdx = selected.dimord.index(prop)
                            propArr = np.unique(
                                selected.data[:, propIdx]).astype(np.intp)
                            assert set(getattr(selected, prop)) == set(
                                getattr(dummy, prop)[propArr])
                            tk = 0
                            for trialno in range(len(dummy.trials)):
                                if solution[
                                        trialno]:  # do not try to compare empty selections
                                    assert np.array_equal(
                                        selected.trials[tk],
                                        dummy.trials[trialno][
                                            solution[trialno], :])
                                    tk += 1

                        # `channel` is a special case for `SpikeData` objects
                        elif dclass == "SpikeData" and prop == "channel":
                            chanIdx = selected.dimord.index("channel")
                            chanArr = np.arange(dummy.channel.size)
                            assert set(selected.data[:, chanIdx]).issubset(
                                chanArr[solution])
                            assert set(selected.channel) == set(
                                dummy.channel[solution])

                        # everything else (that is not a `DiscreteData` child)
                        else:
                            idx = [slice(None)] * len(dummy.dimord)
                            idx[dummy.dimord.index(prop)] = solution
                            assert np.array_equal(
                                np.array(dummy.data)[tuple(idx)],
                                selected.data)
                            assert np.array_equal(
                                getattr(selected, prop),
                                getattr(dummy, prop)[solution])

                    # ensure invalid selection trigger expected errors
                    for ik, isel in enumerate(
                            self.selectDict[prop]["invalid"]):
                        with pytest.raises(
                                self.selectDict[prop]["errors"][ik]):
                            Selector(dummy, {prop + "s": isel})
                else:

                    # ensure objects that don't have a `prop` attribute complain
                    with pytest.raises(SPYValueError):
                        Selector(dummy, {prop + "s": [0]})

            # ensure invalid `toi` + `toilim` specifications trigger expected errors
            if hasattr(dummy, "time") or hasattr(dummy, "trialtime"):
                for selection in ["toi", "toilim"]:
                    for ik, isel in enumerate(
                            self.selectDict[selection]["invalid"]):
                        with pytest.raises(
                                self.selectDict[selection]["errors"][ik]):
                            Selector(dummy, {selection: isel})
                # provide both `toi` and `toilim`
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"toi": [0], "toilim": [0, 1]})
            else:
                # ensure objects that don't have `time` props complain properly
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"toi": [0]})
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"toilim": [0]})

            # ensure invalid `foi` + `foilim` specifications trigger expected errors
            if hasattr(dummy, "freq"):
                for selection in ["foi", "foilim"]:
                    for ik, isel in enumerate(
                            self.selectDict[selection]["invalid"]):
                        with pytest.raises(
                                self.selectDict[selection]["errors"][ik]):
                            Selector(dummy, {selection: isel})
                # provide both `foi` and `foilim`
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"foi": [0], "foilim": [0, 1]})
            else:
                # ensure objects without `freq` property complain properly
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"foi": [0]})
                with pytest.raises(SPYValueError):
                    Selector(dummy, {"foilim": [0]})
Пример #8
0
    def test_dataselection(self):
        dummy = SpectralData(
            data=self.data,
            trialdefinition=self.trl,
            samplerate=self.samplerate,
            taper=["TestTaper_0{}".format(k) for k in range(1, self.nt + 1)])
        trialSelections = [
            "all",  # enforce below selections in all trials of `dummy`
            [3, 1]  # minimally unordered
        ]
        chanSelections = [
            ["channel03", "channel01", "channel01",
             "channel02"],  # string selection w/repetition + unordered
            [4, 2, 2, 5, 5],  # repetition + unorderd
            range(5, 8),  # narrow range
            slice(-2, None)  # negative-start slice
        ]
        toiSelections = [
            "all",  # non-type-conform string
            [0.6],  # single inexact match
            [-0.2, 0.6, 0.9, 1.1, 1.3, 1.6, 1.8, 2.2, 2.45,
             3.]  # unordered, inexact, repetions
        ]
        toilimSelections = [
            [0.5, 1.5],  # regular range
            [1.5, 2.0],  # minimal range (just two-time points)
            [1.0, np.inf]  # unbounded from above
        ]
        foiSelections = [
            "all",  # non-type-conform string
            [2.6],  # single inexact match
            [1.1, 1.9, 2.1, 3.9, 9.2, 11.8, 12.9, 5.1,
             13.8]  # unordered, inexact, repetions
        ]
        foilimSelections = [
            [2, 11],  # regular range
            [1, 2.0],  # minimal range (just two-time points)
            [1.0, np.inf]  # unbounded from above
        ]
        taperSelections = [
            ["TestTaper_03", "TestTaper_01", "TestTaper_01",
             "TestTaper_02"],  # string selection w/repetition + unordered
            [0, 1, 1, 2, 3],  # preserve repetition, don't convert to slice
            range(2, 5),  # narrow range
            slice(0, 5, 2),  # slice w/non-unitary step-size
        ]
        timeSelections = list(zip(["toi"] * len(toiSelections), toiSelections)) \
            + list(zip(["toilim"] * len(toilimSelections), toilimSelections))
        freqSelections = list(zip(["foi"] * len(foiSelections), foiSelections)) \
            + list(zip(["foilim"] * len(foilimSelections), foilimSelections))

        idx = [slice(None)] * len(dummy.dimord)
        timeIdx = dummy.dimord.index("time")
        chanIdx = dummy.dimord.index("channel")
        freqIdx = dummy.dimord.index("freq")
        taperIdx = dummy.dimord.index("taper")

        for trialSel in trialSelections:
            for chanSel in chanSelections:
                for timeSel in timeSelections:
                    for freqSel in freqSelections:
                        for taperSel in taperSelections:
                            kwdict = {}
                            kwdict["trials"] = trialSel
                            kwdict["channels"] = chanSel
                            kwdict[timeSel[0]] = timeSel[1]
                            kwdict[freqSel[0]] = freqSel[1]
                            kwdict["tapers"] = taperSel
                            cfg = StructDict(kwdict)
                            # data selection via class-method + `Selector` instance for indexing
                            selected = dummy.selectdata(**kwdict)
                            selector = Selector(dummy, kwdict)
                            idx[chanIdx] = selector.channel
                            idx[freqIdx] = selector.freq
                            idx[taperIdx] = selector.taper
                            for tk, trialno in enumerate(selector.trials):
                                idx[timeIdx] = selector.time[tk]
                                indexed = dummy.trials[trialno][
                                    idx[0], ...][:, idx[1],
                                                 ...][:, :, idx[2], :][...,
                                                                       idx[3]]
                                assert np.array_equal(
                                    selected.trials[tk].squeeze(),
                                    indexed.squeeze())
                            cfg.data = dummy
                            cfg.out = SpectralData(
                                dimord=SpectralData._defaultDimord)
                            # data selection via package function and `cfg`: ensure equality
                            selectdata(cfg)
                            assert np.array_equal(cfg.out.channel,
                                                  selected.channel)
                            assert np.array_equal(cfg.out.freq, selected.freq)
                            assert np.array_equal(cfg.out.taper,
                                                  selected.taper)
                            assert np.array_equal(cfg.out.data, selected.data)