I have a custom transformer class called
NiftiProcessor which is a wrapper around
NiftiMasker. This class takes one or multiple images, binarizes them depending on a threshold and passes them over to
NiftiMasker. This class is also supposed to take no image(s) at all, in this case
NiftiMasker should be initialized with the keyword argument
mask_img = None and
mask_strategy = 'template'.
The option for one or multiple images work, however if I initialize
tpl_imgs = None. I get the following error:
TypeError: Data given cannot be loaded because it is not compatible with nibabel format:
Strangely enough, If I initialize
NiftiMasker with the (as I hope) same arguments everything seems to work fine. I checked my code several times and actually
NiftiProcessor should ‘fall back’ to the same settings as initializing
NiftiMasker. See the section:
if self.tpl_imgs is None: self.mask_img_ = None self.mask_strategy_ = 'template'
Here’s the code for my class:
class NiftiProcessor(BaseEstimator,TransformerMixin): '''Wrapper Class around NiftiMasker. Parameters ---------- tpl_imgs: One Niimg-like object or a list of multiple Niimg-like objects. threshold: float or str See documentation of NiftiMasker for all other parameters. http://nilearn.github.io/modules/generated/nilearn.input_data.NiftiMasker.html ''' def __init__(self, tpl_imgs=None, threshold=None,smoothing_fwhm=None, standardize=True,memory=None): self.tpl_imgs = tpl_imgs self.threshold = threshold self.smoothing_fwhm = smoothing_fwhm self.standardize = standardize self.memory = memory def fit(self, X, y=None): if self.tpl_imgs is None: self.mask_img_ = None self.mask_strategy_ = 'template' # if one or multiple masks are provided set mask_strategy to None. # you could also set it to one of the possible strategies, they would # still be ignored since a mask image is provided. But None is more # explicit here. elif isinstance(self.tpl_imgs,list): self.mask_img_ = intersect_masks( [binarize_img(img,self.threshold) for img in self.tpl_imgs], threshold=0, connected=False ) self.mask_strategy_ = None else: self.mask_img_ = binarize_img(self.tpl_imgs,self.threshold) self.mask_strategy_ = None self.masker_ = NiftiMasker(mask_img=self.mask_img_, smoothing_fwhm=self.smoothing_fwhm, standardize=self.standardize, mask_strategy=self.mask_strategy_, memory=self.memory).fit() return self def transform(self,X,y=None): if not hasattr(self, 'mask_img_'): raise ValueError('transformer not fitted yet.') return self.masker_.transform(X)
And here are two ways to initialize both classes (
NiftiMasker works, whereas
NiftiProcessor throws error, although they should be the same):
masked_mri_niftiprocessor = masking.NiftiProcessor(tpl_imgs=None, threshold=MASK_THRESHOLD, smoothing_fwhm=8, standardize=True, memory=niftiprocessor_cache ).fit_transform(imgs_paths) masked_mri_niftimasker = NiftiMasker(mask_img=None, mask_strategy='template', smoothing_fwhm=8, standardize=True, memory=niftimasker_cache ).fit_transform(imgs_paths)
Does anyone know what could have gone wrong here?