Ejemplo n.º 1
0
    def __getitem__(self, parameters) -> _SWIG_CALLABLE_TYPE:
        """Return the class which corresponds to the given template parameters.

        parameters can be:
            - a single parameter (Ex: itk.Index[2])
            - a list of elements (Ex: itk.Image[itk.UC, 2])
        """

        parameters_type = type(parameters)
        if (parameters_type is not tuple) and (parameters_type is not list):
            # parameters is a single element.
            # include it in a list to manage the 2 cases in the same way
            parameters = [parameters]

        cleanParameters = []
        for param in parameters:
            # In the case of itk class instance, get the class
            name: str = param.__class__.__name__
            isclass: bool = inspect.isclass(param)
            if not isclass and name.startswith("itk") and name != "itkCType":
                param = param.__class__

            # append the parameter to the list. If it's not a supported type,
            # it is not in the dictionary and we will raise an exception below
            cleanParameters.append(param)

        key = tuple(cleanParameters)
        if self.__template__.get(key, None) is None:
            self._LoadModules()
        try:
            this_item = self.__template__[key]
        except KeyError:
            import itk

            raise itk.TemplateTypeError(self, key)
        return this_item
Ejemplo n.º 2
0
    def New(self, *args, **kwargs):
        """Instantiate the template with a type implied from its input.

        Template type specification can be avoided by assuming that the type's
        first template argument should have the same type as its primary input.
        This is generally true. If it is not true, then specify the types
        explicitly.

        For example, instead of the explicit type specification::

          median = itk.MedianImageFilter[ImageType, ImageType].New()
          median.SetInput(reader.GetOutput())

        call::

          median = itk.MedianImageFilter.New(Input=reader.GetOutput())

        or, the shortened::

          median = itk.MedianImageFilter.New(reader.GetOutput())

        or:

          median = itk.MedianImageFilter.New(reader)"""
        import itk

        keys = self.keys()
        cur = itk.auto_pipeline.current
        if self.__name__ == "itk::ImageFileReader":
            return self._NewImageReader(
                itk.ImageFileReader, False, "FileName", *args, **kwargs
            )
        elif self.__name__ == "itk::ImageSeriesReader":
            # Only support `FileNames`, not `FileName`, to simplify the logic and avoid having
            # to deal with checking if both keyword arguments are given.
            return self._NewImageReader(
                itk.ImageSeriesReader, True, "FileNames", *args, **kwargs
            )
        elif self.__name__ == "itk::MeshFileReader":
            return self._NewMeshReader(itk.MeshFileReader, *args, **kwargs)
        primary_input_methods = ("Input", "InputImage", "Input1")

        def ttype_for_input_type(keys_l, input_type_l):
            keys_first = list(filter(lambda k: k[0] == input_type_l, keys_l))
            # If there is more than one match, prefer the filter where the
            # second template argument, typically the second input or the
            # output, has the same type as the input
            keys_second = list(
                filter(lambda k: len(k) > 1 and k[1] == input_type_l, keys_first)
            )
            if len(keys_second):
                return keys_second
            return keys_first

        input_type = None
        if "ttype" in kwargs and keys:
            # Convert `ttype` argument to `tuple` as filter keys are tuples.
            # Note that the function `itk.template()` which returns the template
            # arguments of an object returns tuples and its returned value
            # should be usable in this context.
            # However, it is easy for a user to pass a list (e.g. [ImageType, ImageType]) or
            # a type (e.g., ImageType), and these need to work too.
            ttype = kwargs.pop("ttype")
            if not isinstance(ttype, tuple):
                if isinstance(ttype, list):
                    ttype = tuple(ttype)
                else:
                    ttype = (ttype,)
            # If there is not the correct number of template parameters, throw an error.
            if len(ttype) != len(list(keys)[0]):
                raise RuntimeError(
                    "Expected %d template parameters. %d parameters given."
                    % (len(list(keys)[0]), len(ttype))
                )
            keys = [k for k in keys if k == ttype]
        elif len(args) != 0:
            # try to find a type suitable for the primary input provided
            input_type = output(args[0]).__class__
            keys = ttype_for_input_type(keys, input_type)
        elif set(primary_input_methods).intersection(kwargs.keys()):
            for method in primary_input_methods:
                if method in kwargs:
                    input_type = output(kwargs[method]).__class__
                    keys = ttype_for_input_type(keys, input_type)
                    break
        elif cur is not None and len(cur) != 0:
            # try to find a type suitable for the input provided
            input_type = output(cur).__class__
            keys = ttype_for_input_type(keys, input_type)

        if len(keys) == 0:
            if not input_type:
                raise RuntimeError(
                    """No suitable template parameter can be found.

Please specify an input via the first argument, the 'ttype' keyword parameter,
or via one of the following keyword arguments: %s"""
                    % ", ".join(primary_input_methods)
                )
            else:
                import itk

                raise itk.TemplateTypeError(self, input_type)
        return self[list(keys)[0]].New(*args, **kwargs)