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 NiftiProcessor
with tpl_imgs = None
. I get the following error:
TypeError: Data given cannot be loaded because it is not compatible with nibabel format:
None
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?