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

Node that simply maps numpy array to new value #50

Open
hanslovsky opened this issue Feb 7, 2019 · 2 comments
Open

Node that simply maps numpy array to new value #50

hanslovsky opened this issue Feb 7, 2019 · 2 comments

Comments

@hanslovsky
Copy link
Contributor

For prototyping it would be very useful to have a node that applies a user-provided mapping to the voxels of an array for a key/multiple keys (the shape of the data may not change). Is there a node with such functionality in gunpowder?

I currently have a MapNumpyArray node that does exactly that:

class MapNumpyArray(BatchFilter):
    def __init__(
            self,
            mapping,
            *keys):
        super(BatchFilter, self).__init__()
        self.keys    = keys
        self.mapping = mapping

    def setup(self):
        pass

    def prepare(self, request):
        pass

    def process(self, batch, request):

        for key in self.keys:
            if not key in request:
                logger.debug('Ignoring key %s: not in request %s', key, request)
                continue

            assert key in batch.arrays, 'Requested key %s not in batch arrays %s' % (key, batch)

            array = batch.arrays[key]
            logger.debug('Array data dtype for key %s before mapping: %s', key, array.data.dtype)
            mapped_data = self.mapping(array.data)
            assert mapped_data.shape == array.data.shape, 'Mapping must not change shape of data: Original shape is {}, mapped shape is {}'.format(array.data.shape, mapped_data.shape)
            array.data = mapped_data
            logger.debug('Array data dtype for key %s after mapping: %s', key, batch.arrays[key].data.dtype)

Could this be useful for the broader gunpowder community? If so, I'll file a PR.

@aschampion
Copy link
Contributor

I also have a custom node that does something similar (MapLabels), but in my case found I was able to abuse ExcludeLabels to the same end with only slightly worse performance.

One consideration if you want to PR if that if you change the dtype of the data via mapping, you will need to change the spec in setup, something like (pseudo):

    def setup(self):
        ...
        if self.output_dtype:
            spec = self.spec[key].copy()
            spec.dtype = self.output_dtype
            self.updates(key, spec)

@hanslovsky
Copy link
Contributor Author

One consideration if you want to PR if that if you change the dtype of the data via mapping, you will need to change the spec in setup, something like (pseudo):

Interesting, that is exactly what I used the node for initially (np.require) but I never thought about changing the output dtype.

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

No branches or pull requests

3 participants