Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Expose _apply_op as a public method #5

Open
SimonBiggs opened this issue Jul 20, 2021 · 0 comments
Open

Feature request: Expose _apply_op as a public method #5

SimonBiggs opened this issue Jul 20, 2021 · 0 comments

Comments

@SimonBiggs
Copy link

SimonBiggs commented Jul 20, 2021

Hi,

I have found the private function _apply_op to be quite useful for custom lazy computation. For example:

import ml_collections

structures = ml_collections.FieldReference(
    [
        "parotid_right",
        "parotid_left",
        "brainstem",
        "spinal_cord",
    ],
    field_type=list,
)

################################################
number_of_structures = structures._apply_op(len)
number_of_structures._field_type = int
################################################

edge_length = ml_collections.FieldReference(512, field_type=int)

cfg = ml_collections.ConfigDict(
    {
        "structures": structures,
        "edge_length": edge_length,
        "mask_shape": (edge_length, edge_length, number_of_structures),
    }
)

assert cfg.mask_shape == (512, 512, 4)  # Passes

cfg.structures = ["brainstem", "spinal_cord"]
cfg.edge_length = 64
assert cfg.mask_shape == (64, 64, 2)  # Passes

Might it be possible that this method be exposed as a first class method named apply_op (or more simply apply)? I'd be happy to make a PR including the above as a test if there is interest in making this design adjustment.

Here is an example implementation:

def apply(parent: ml_collections.FieldReference, fn, field_type=None):
    child = parent._apply_op(fn)  # pylint: disable = protected-access

    if field_type is not None:
        child._field_type = field_type  # pylint: disable = protected-access

    a_child_value = child.get()
    if not isinstance(
        a_child_value, child._field_type  # pylint: disable = protected-access
    ):
        raise TypeError(
            f"Expected operation result to be of type {field_type}. "
            f"Instead however it was {type(a_child_value)}. "
            "Adjust the `field_type` parameter accordingly."
        )

    return child

and a corresponding test:

def test_config_apply():
    fr = ml_collections.FieldReference("a,b,c", field_type=str)

    def fn(string):
        return string.split(",")

    with pytest.raises(TypeError):
        apply(fr, fn)

    new_fr = apply(fr, fn, field_type=list)
    assert new_fr.get() == ["a", "b", "c"]

Cheers,
Simon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant