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
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)