Пример #1
0
def test_pf_export_non_scalar_filtered_issue_166():
    h5path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
    # initialize PlugInFeature instance
    info = example_plugin_info_non_scalar_feature()
    info["feature shapes"] = [(80, 250)]
    pf = PlugInFeature("image_gauss_filter", info)

    with dclab.new_dataset(h5path) as ds:
        # extract the feature information from the dataset
        assert pf in PlugInFeature.features
        image_gauss_filter = ds[pf.feature_name]
        assert np.all(ds.filter.manual)  # just checking the default
        ds.filter.manual[0] = False
        ds.filter.manual[2] = False
        image_gauss_filter_filtered = np.array(
            image_gauss_filter[ds.filter.manual], copy=True)
        ds.apply_filter()

        # export the data to a new file
        expath = h5path.with_name("exported.rtdc")
        ds.export.hdf5(expath, features=[pf.feature_name], filtered=True)

    # make sure that worked
    with h5py.File(expath, "r") as h5:
        assert pf.feature_name in h5["events"]
        assert np.allclose(h5["events"][pf.feature_name],
                           image_gauss_filter_filtered)
Пример #2
0
def test_pf_export_non_scalar_single_event():
    h5path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
    # initialize PlugInFeature instance
    info = example_plugin_info_non_scalar_feature()
    info["feature shapes"] = [(80, 250)]
    pf = PlugInFeature("image_gauss_filter", info)

    with dclab.new_dataset(h5path) as ds:
        # extract the feature information from the dataset
        assert pf in PlugInFeature.features
        image_gauss_filter = ds[pf.feature_name]

        # export the data to a new file
        expath = h5path.with_name("exported.rtdc")
        ds.export.hdf5(expath, features=["image", pf.feature_name])
        # write another single event
        with dclab.RTDCWriter(expath) as hw:
            hw.store_feature(pf.feature_name, ds["image"][0])
            hw.store_feature("image", ds["image"][0])

    # make sure that worked
    with h5py.File(expath, "r") as h5:
        assert pf.feature_name in h5["events"]
        assert np.allclose(h5["events"][pf.feature_name][:-1],
                           image_gauss_filter)
        assert np.allclose(h5["events"][pf.feature_name][-1],
                           h5["events/image"][0])
Пример #3
0
def test_pf_export_and_load():
    """Check that exported and loaded hdf5 file will keep a plugin feature"""
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    # initialize PlugInFeature instance
    info = example_plugin_info_single_feature()
    pf = PlugInFeature("circ_per_area", info)

    with dclab.new_dataset(h5path) as ds:
        # extract the feature information from the dataset
        assert pf in PlugInFeature.features
        circ_per_area = ds[pf.feature_name]

        # export the data to a new file
        expath = h5path.with_name("exported.rtdc")
        ds.export.hdf5(expath, features=ds.features_innate + [pf.feature_name])

    # make sure that worked
    with h5py.File(expath, "r") as h5:
        assert pf.feature_name in h5["events"]
        assert np.allclose(h5["events"][pf.feature_name], circ_per_area)

    # now check again with dclab
    with dclab.new_dataset(expath) as ds2:
        assert pf in PlugInFeature.features
        assert pf.feature_name in ds2
        assert pf.feature_name in ds2.features_innate
        assert np.allclose(ds2[pf.feature_name], circ_per_area)

        # and a control check
        remove_plugin_feature(pf)
        assert pf.feature_name not in ds2
Пример #4
0
def test_pf_incorrect_input_method():
    """Raise error when method is not callable"""
    info = example_plugin_info_single_feature()
    # set `info["method"]` to something that isn't callable
    info["method"] = "this_is_a_string"
    with pytest.raises(ValueError, match="is not callable"):
        PlugInFeature("circ_per_area", info)
Пример #5
0
def test_pf_export_non_scalar_filtered_from_file_issue_166():
    h5path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
    expath = h5path.with_name("exported.rtdc")
    # initialize PlugInFeature instance
    info = example_plugin_info_non_scalar_feature()
    info["feature shapes"] = [(80, 250)]
    pf = PlugInFeature("image_gauss_filter", info)

    # write the plugin feature data to an HDF5 file
    with dclab.new_dataset(h5path) as ds:
        # extract the feature information from the dataset
        ds.export.hdf5(expath, features=[pf.feature_name])

    # remove all plugin features and work with temporary feature
    remove_all_plugin_features()

    # try to load the plugin feature data from that HDF5 file and
    # export it again (this time, the exporter has to get the data
    # from the H5File object).
    expath2 = h5path.with_name("exported2.rtdc")
    dclab.register_temporary_feature("image_gauss_filter", is_scalar=False)
    with dclab.new_dataset(expath) as ds2:
        ds2.export.hdf5(expath2,
                        features=["image_gauss_filter"],
                        filtered=True)

    # make sure that worked
    with h5py.File(expath2, "r") as h5:
        assert "image_gauss_filter" in h5["events"]
Пример #6
0
def test_pf_initialize_plugin_features_multiple():
    """Check multiple plugin features exist independant of loaded dataset"""
    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    assert "circ_per_area" not in ds.features_innate
    assert "circ_times_area" not in ds.features_innate
    info = example_plugin_info_multiple_feature()
    PlugInFeature("circ_per_area", info)
    PlugInFeature("circ_times_area", info)

    assert "circ_per_area" in ds
    assert "circ_times_area" in ds
    assert dclab.dfn.feature_exists("circ_per_area")
    assert dclab.dfn.feature_exists("circ_times_area")
    circ_per_area = ds["circ_per_area"]
    circ_times_area = ds["circ_times_area"]
    assert np.allclose(circ_per_area, ds["circ"] / ds["area_um"])
    assert np.allclose(circ_times_area, ds["circ"] * ds["area_um"])
Пример #7
0
def test_pf_attribute_ancill_info():
    """Check the plugin feature attribute input to AncillaryFeature"""
    info = example_plugin_info_single_feature()
    pf = PlugInFeature("circ_per_area", info)
    assert pf.plugin_feature_info["feature name"] == "circ_per_area"
    assert pf.plugin_feature_info["method"] is compute_single_plugin_feature
    assert pf.plugin_feature_info["config required"] == []
    assert pf.plugin_feature_info["features required"] == ["circ", "area_um"]
Пример #8
0
def test_pf_wrong_data_shape_1():
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        info = example_plugin_info_single_feature()
        info["scalar feature"] = [False]
        pf = PlugInFeature("circ_per_area", info)
        with pytest.raises(ValueError, match="is not a scalar feature"):
            ds[pf.feature_name]
Пример #9
0
def test_pf_with_feature_label():
    """Check that a plugin feature label is added to definitions"""
    info = example_plugin_info_single_feature()
    info["feature labels"] = ["Circ / Area [1/µm²]"]
    feature_name = "circ_per_area"
    PlugInFeature(feature_name, info)
    assert dclab.dfn.feature_exists("circ_per_area")
    label = dclab.dfn.get_feature_label("circ_per_area")
    assert label == "Circ / Area [1/µm²]"
Пример #10
0
def test_pf_wrong_data_shape_2():
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        info = example_plugin_info_single_feature()
        info["scalar feature"] = [True]
        info["method"] = lambda x: np.arange(len(ds) * 2).reshape(-1, 2)
        pf = PlugInFeature("circ_per_area", info)
        with pytest.raises(ValueError, match="is a scalar feature"):
            ds[pf.feature_name]
Пример #11
0
def test_pf_input_no_feature_labels():
    """Check that feature labels are populated even if not given"""
    info = example_plugin_info_single_feature()
    info.pop("feature labels")
    feature_name = "circ_per_area"
    pf = PlugInFeature(feature_name, info)
    assert dclab.dfn.feature_exists(feature_name)
    label = dclab.dfn.get_feature_label(feature_name)
    assert label == "Plugin feature {}".format(feature_name)
    assert label == pf.plugin_feature_info["feature label"]
Пример #12
0
def test_pf_initialize_plugin_feature_non_scalar():
    """Check that the non-scalar plugin feature works"""
    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    info = example_plugin_info_non_scalar_feature()
    PlugInFeature("image_gauss_filter", info)
    assert "image_gauss_filter" in ds

    image_gauss_filter = ds["image_gauss_filter"]
    assert np.allclose(image_gauss_filter,
                       gaussian_filter(ds["image"], sigma=(0, 1, 1)))
Пример #13
0
def test_pf_inherited_scalar():
    """Scalar inherited PluginFeatures should be a 1D np.ndarray"""
    info = example_plugin_info_single_feature()
    PlugInFeature("circ_per_area", info)
    with dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip")) as ds:
        ds.filter.manual[2] = False
        ch = dclab.new_dataset(ds)
        assert "circ_per_area" in ch
        assert isinstance(ch["circ_per_area"], np.ndarray)
        assert ch["circ_per_area"].ndim == 1
Пример #14
0
def test_pf_inherited_non_scalar():
    """Non scalar inherited plugin features should be of class ChildNDArray"""
    info = example_plugin_info_non_scalar_feature()
    PlugInFeature("image_gauss_filter", info)
    with dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip")) as ds:
        ds.filter.manual[2] = False
        ch = dclab.new_dataset(ds)
        assert "image_gauss_filter" in ch
        assert isinstance(ch["image_gauss_filter"], ChildNDArray)
        assert len(ch["image_gauss_filter"].shape) == 3
Пример #15
0
def test_pf_exists_in_hierarchy():
    """Test that RTDCHierarchy works with PlugInFeature"""
    info = example_plugin_info_single_feature()
    pf = PlugInFeature("circ_per_area", info)
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        assert pf.feature_name in ds
        assert dclab.dfn.feature_exists(pf.feature_name)
        child = dclab.new_dataset(ds)
        assert pf.feature_name in child
Пример #16
0
def test_pf_wrong_length_2():
    """plugin feature should have same length"""
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        info = example_plugin_info_single_feature()
        info["method"] = lambda x: np.arange(len(ds) * 2)
        pf = PlugInFeature("circ_per_area", info)
        with pytest.warns(BadFeatureSizeWarning,
                          match="to match event number"):
            ds[pf.feature_name]
Пример #17
0
def test_pf_filtering_with_plugin_feature():
    """Filtering with plugin feature"""
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        info = example_plugin_info_single_feature()
        pf = PlugInFeature("circ_per_area", info)

        ds.config["filtering"][f"{pf.feature_name} min"] = 0.030
        ds.config["filtering"][f"{pf.feature_name} max"] = 0.031
        ds.apply_filter()
        assert np.sum(ds.filter.all) == 1
        assert ds.filter.all[4]
Пример #18
0
def test_pf_initialize_plugin_feature_single():
    """Check that single plugin feature exists independant of loaded dataset"""
    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    info = example_plugin_info_single_feature()
    PlugInFeature("circ_per_area", info)
    assert "circ_per_area" in ds

    circ_per_area = ds["circ_per_area"]
    assert np.allclose(circ_per_area, ds["circ"] / ds["area_um"])

    # check that PlugInFeature exists independent of loaded ds
    ds2 = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    assert "circ_per_area" in ds2
Пример #19
0
def test_pf_initialize_plugin_after_loading():
    """plugin feature loads correctly after feature added to hdf5 file"""
    h5path = retrieve_data("fmt-hdf5_fl_2018.zip")
    with dclab.new_dataset(h5path) as ds:
        circ_per_area = compute_single_plugin_feature(ds)
    with h5py.File(h5path, "a") as h5:
        h5["events"]["circ_per_area"] = circ_per_area
    with dclab.new_dataset(h5path) as ds:
        assert "circ_per_area" not in ds
        info = example_plugin_info_single_feature()
        PlugInFeature("circ_per_area", info)
        assert "circ_per_area" in ds
        assert "circ_per_area" in ds.features_innate
Пример #20
0
def test_pf_with_no_feature_label():
    """A feature label of None is replaced with a real feature label

    Show that `feature_label=None` will still give a descriptive
    feature label. See `dclab.dfn._add_feature_to_definitions` for details.
    """
    info = example_plugin_info_single_feature()
    info["feature labels"] = [None]
    feature_name = "circ_per_area"
    PlugInFeature(feature_name, info)
    assert dclab.dfn.feature_exists("circ_per_area")
    label = dclab.dfn.get_feature_label("circ_per_area")
    assert label is not None
    assert label == "Plugin feature {}".format(feature_name)
Пример #21
0
def test_pf_with_empty_feature_label_string():
    """An empty string is replaced with a real feature label

    Show that an empty `feature_label` will still give a descriptive
    feature label. See `dclab.dfn._add_feature_to_definitions` for details.
    """
    info = example_plugin_info_single_feature()
    info["feature labels"] = [""]
    feature_name = "circ_per_area"
    PlugInFeature(feature_name, info)
    assert dclab.dfn.feature_exists("circ_per_area")
    label = dclab.dfn.get_feature_label("circ_per_area")
    assert label != ""
    assert label == "Plugin feature {}".format(feature_name)
Пример #22
0
def test_pf_load_scalar_plugin_data():
    """Test loading scalar plugin data return np.ndarray"""
    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    info = example_plugin_info_single_feature()
    PlugInFeature("circ_per_area", info)
    assert isinstance(ds["circ_per_area"], np.ndarray)

    # Exporting the rtdc-file including the plugin-feature and then reloading
    # it should still load scalar plugin data as np.ndarray
    tdir = tempfile.mkdtemp()
    pdir = pathlib.Path(tdir)
    pfile = pdir / "tmp.rtdc"
    features = ds.features + ["circ_per_area"]
    ds.export.hdf5(pfile, features=features)
    ds2 = dclab.new_dataset(pfile)
    assert isinstance(ds2["circ_per_area"], np.ndarray)
Пример #23
0
def test_pf_export_non_scalar():
    h5path = retrieve_data("fmt-hdf5_image-bg_2020.zip")
    # initialize PlugInFeature instance
    info = example_plugin_info_non_scalar_feature()
    pf = PlugInFeature("image_gauss_filter", info)

    with dclab.new_dataset(h5path) as ds:
        # extract the feature information from the dataset
        assert pf in PlugInFeature.features
        image_gauss_filter = ds[pf.feature_name]

        # export the data to a new file
        expath = h5path.with_name("exported.rtdc")
        ds.export.hdf5(expath, features=[pf.feature_name])

    # make sure that worked
    with h5py.File(expath, "r") as h5:
        assert pf.feature_name in h5["events"]
        assert np.allclose(h5["events"][pf.feature_name], image_gauss_filter)
Пример #24
0
def test_pf_with_user_config_section_fails():
    """Use a plugin feature with the user defined config section"""
    info = {
        "method": compute_with_user_section,
        "feature names": ["area_of_region"],
        "config required": [["user", ["n_constrictions"]]]
    }
    PlugInFeature("area_of_region", info)

    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    # show that the plugin feature is not available before setting the
    # user metadata
    ds.config["user"].clear()
    with pytest.raises(KeyError,
                       match=r"Feature \'area_of_region\' does not exist"):
        ds["area_of_region"]
    # show that the plugin fails when the user metadata type is wrong
    ds.config["user"]["n_constrictions"] = 4.99
    with pytest.raises(AssertionError, match="should be an integer value"):
        ds["area_of_region"]
Пример #25
0
def test_pf_load_non_scalar_plugin_data():
    """Test loading non-scalar plugin data format"""
    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    info = example_plugin_info_non_scalar_feature()
    info["feature shapes"] = [(80, 250)]
    PlugInFeature("image_gauss_filter", info)

    # Accessing non-scalar plugin data without prior saving and storing data in
    # HDF5-format should return already computed data as np.ndarray
    assert isinstance(ds["image_gauss_filter"], np.ndarray)

    # Exporting the rtdc-file including the plugin-feature and then reloading
    # it should load the non-scalar plugin data as h5py.Dataset
    tdir = tempfile.mkdtemp()
    pdir = pathlib.Path(tdir)
    pfile = pdir / "tmp.rtdc"
    features = ds.features + ["image_gauss_filter"]
    ds.export.hdf5(pfile, features=features)
    ds2 = dclab.new_dataset(pfile)
    assert isinstance(ds2["image_gauss_filter"], h5py.Dataset)
Пример #26
0
def test_pf_with_user_config_section():
    """Use a plugin feature with the user defined config section"""
    info = {
        "method": compute_with_user_section,
        "feature names": ["area_of_region"],
        "config required": [["user", ["n_constrictions"]]]
    }
    PlugInFeature("area_of_region", info)

    ds = dclab.new_dataset(retrieve_data("fmt-hdf5_fl_2018.zip"))
    assert "area_of_region" not in ds, "not available b/c missing metadata"
    # add some metadata to the user config section
    metadata = {"channel": True, "n_constrictions": 3}
    ds.config["user"].update(metadata)
    assert ds.config["user"] == metadata
    assert "area_of_region" in ds, "available b/c metadata is set"

    area_of_region1 = ds["area_of_region"]
    area_of_region1_calc = (ds["area_um"] *
                            ds.config["user"]["n_constrictions"])
    assert np.allclose(area_of_region1, area_of_region1_calc)
Пример #27
0
def test_pf_minimum_info_input():
    """Only method and feature names are required to create PlugInFeature"""
    info = {
        "method": compute_single_plugin_feature,
        "feature names": ["circ_per_area"]
    }
    pf = PlugInFeature("circ_per_area", info)

    # check that all other plugin_feature_info is populated
    assert "method" in pf.plugin_feature_info
    assert callable(pf.plugin_feature_info["method"])
    assert "description" in pf.plugin_feature_info
    assert "long description" in pf.plugin_feature_info
    assert "feature name" in pf.plugin_feature_info
    assert "feature label" in pf.plugin_feature_info
    assert "features required" in pf.plugin_feature_info
    assert "config required" in pf.plugin_feature_info
    assert "method check required" in pf.plugin_feature_info
    assert "scalar feature" in pf.plugin_feature_info
    assert "version" in pf.plugin_feature_info
    assert "plugin path" in pf.plugin_feature_info
Пример #28
0
def test_pf_attribute_plugin_feature_info():
    """Check the plugin feature info attribute"""
    info = example_plugin_info_single_feature()
    # comparing lambda functions fails due to differing memory locations
    info.pop("method check required")
    pf = PlugInFeature("circ_per_area", info)
    pf.plugin_feature_info.pop("method check required")
    plugin_feature_info = {
        "method": compute_single_plugin_feature,
        "description": "This plugin will compute a feature",
        "long description": "Even longer description that "
        "can span multiple lines",
        "feature name": "circ_per_area",
        "feature label": "Circularity per Area",
        "feature shape": (1, ),
        "features required": ["circ", "area_um"],
        "config required": [],
        "scalar feature": True,
        "version": "0.1.0",
        "plugin path": None,
        "identifier": "3a3e72c4cb015424ebbe6d4af63f2170",
    }
    assert pf.plugin_feature_info == plugin_feature_info
Пример #29
0
def test_pf_input_no_scalar_feature():
    """Check that scalar feature bools are populated even if not given"""
    info = example_plugin_info_single_feature()
    info.pop("scalar feature")
    pf = PlugInFeature("circ_per_area", info)
    assert pf.plugin_feature_info["scalar feature"]
Пример #30
0
def test_pf_try_existing_feature_fails():
    """An existing feature name is not allowed"""
    info = example_plugin_info_single_feature()
    info["feature names"] = ["deform"]
    with pytest.raises(ValueError, match="Feature 'deform' already exists"):
        PlugInFeature("deform", info)