<commit_before>"""
Transformer used to apply basic transformations on MRI data.
"""
# Author: <NAME>, <NAME>
# License: simplified BSD


import numpy as np
from sklearn.externals.joblib import Memory

from nibabel import Nifti1Image

from .. import masking
from .. import resampling
from .. import utils
from .base_masker import BaseMasker

class NiftiMultiMasker(BaseMasker):
    """Nifti data loader with preprocessing for multiple subjects

    Parameters
    ----------
    mask: 3D numpy matrix, optional
        Mask of the data. If not given, a mask is computed in the fit step.

    mask_connected: boolean, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_opening: boolean, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_lower_cutoff: float, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_upper_cutoff: float, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    target_affine: 3x3 or 4x4 matrix, optional
        This parameter is passed to resampling.resample_img. Please see the
        related documentation for details.

    target_shape: 3-tuple of integers, optional
        This parameter is passed to resampling.resample_img. Please see the
        related documentation for details.
        
    smooth: False or float, optional
        If smooth is not False, it gives the size, in voxel of the
        spatial smoothing to apply to the signal.

    confounds: CSV file path or 2D matrix
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    detrend: boolean, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    low_pass: False or float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    high_pass: False or float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    t_r: float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details
        
    verbose: interger, optional
        Indicate the level of verbosity. By default, nothing is printed

    See also
    --------
    nisl.masking.compute_epi_mask
    resampling.resample_img
    masking.apply_mask
    signals.clean
    """

    def __init__(self, sessions=None, mask=None, mask_connected=True,
            mask_opening=False, mask_lower_cutoff=0.2, mask_upper_cutoff=0.9,
            smooth=False, confounds=None, detrend=False,
            target_affine=None, target_shape=None, low_pass=None,
            high_pass=None, t_r=None, transpose=False,
            memory=Memory(cachedir=None, verbose=0),
            transform_memory=Memory(cachedir=None, verbose=0), verbose=0):
        # Mask is compulsory or computed
        self.mask = mask
        self.mask_connected = mask_connected
        self.mask_opening = mask_opening
        self.mask_lower_cutoff = mask_lower_cutoff
        self.mask_upper_cutoff = mask_upper_cutoff
        self.smooth = smooth
        self.confounds = confounds
        self.detrend = detrend
        self.target_affine = target_affine
        self.target_shape = target_shape
        self.low_pass = low_pass
        self.high_pass = high_pass
        self.t_r = t_r
        self.memory = memory
        self.transform_memory = transform_memory
        self.verbose = verbose
        self.sessions = sessions
        self.transpose = transpose

    def fit(self, niimgs, y=None):
        """Compute the mask corresponding to the data

        Parameters
        ----------
        niimgs: list of filenames or NiImages
            Data on which the mask must be calculated. If this is a list,
            the affine is considered the same for all.
        """

        memory = self.memory
        if isinstance(memory, basestring):
            memory = Memory(cachedir=memory)

        # Load data (if filenames are given, load them)
        if self.verbose > 0:
            print "[%s.fit] Loading data" % self.__class__.__name__
        data = []
        for niimg in niimgs:
            data.append(utils.check_niimgs(niimg, accept_3d=True))

        # Compute the mask if not given by the user
        if self.mask is None:
            if self.verbose > 0:
                print "[%s.fit] Computing the mask" % self.__class__.__name__
            mask = memory.cache(masking.compute_session_epi_mask)(
                                data,
                                connected=self.mask_connected,
                                opening=self.mask_opening,
                                lower_cutoff=self.mask_lower_cutoff,
                                upper_cutoff=self.mask_upper_cutoff,
                                verbose=(self.verbose -1))
            self.mask_ = Nifti1Image(mask.astype(np.int), data[0].get_affine())
        else:
			self.mask_ = utils.check_niimg(self.mask)

        # If resampling is requested, resample also the mask
        # Resampling: allows the user to change the affine, the shape or both
        if self.verbose > 0:
            print "[%s.transform] Resampling mask" % self.__class__.__name__
        self.mask_ = memory.cache(resampling.resample_img)(self.mask_,
                target_affine=self.target_affine,
                target_shape=self.target_shape,
                copy=(self.target_affine is not None and
                      self.target_shape is not None))

        return self

    def transform(self, niimgs):
        data = []
        for index, niimg in enumerate(niimgs):
            if self.confounds is not None:
                data.append(self.preprocess_niimgs(niimg,
                    confounds=self.confounds[index]))
            else:
                data.append(self.preprocess_niimgs(niimg))
        return data

<commit_msg>Raise error if affine is different across subjects<commit_after>"""
Transformer used to apply basic transformations on MRI data.
"""
# Author: <NAME>, <NAME>
# License: simplified BSD


import numpy as np
from sklearn.externals.joblib import Memory

from nibabel import Nifti1Image

from .. import masking
from .. import resampling
from .. import utils
from .base_masker import BaseMasker

class NiftiMultiMasker(BaseMasker):
    """Nifti data loader with preprocessing for multiple subjects

    Parameters
    ----------
    mask: 3D numpy matrix, optional
        Mask of the data. If not given, a mask is computed in the fit step.

    mask_connected: boolean, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_opening: boolean, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_lower_cutoff: float, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    mask_upper_cutoff: float, optional
        If mask is None, this parameter is passed to masking.compute_epi_mask
        for mask computation. Please see the related documentation for details.

    target_affine: 3x3 or 4x4 matrix, optional
        This parameter is passed to resampling.resample_img. Please see the
        related documentation for details.

    target_shape: 3-tuple of integers, optional
        This parameter is passed to resampling.resample_img. Please see the
        related documentation for details.
        
    smooth: False or float, optional
        If smooth is not False, it gives the size, in voxel of the
        spatial smoothing to apply to the signal.

    confounds: CSV file path or 2D matrix
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    detrend: boolean, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    low_pass: False or float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    high_pass: False or float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details

    t_r: float, optional
        This parameter is passed to signals.clean. Please see the related
        documentation for details
        
    verbose: interger, optional
        Indicate the level of verbosity. By default, nothing is printed

    See also
    --------
    nisl.masking.compute_epi_mask
    resampling.resample_img
    masking.apply_mask
    signals.clean
    """

    def __init__(self, sessions=None, mask=None, mask_connected=True,
            mask_opening=False, mask_lower_cutoff=0.2, mask_upper_cutoff=0.9,
            smooth=False, confounds=None, detrend=False,
            target_affine=None, target_shape=None, low_pass=None,
            high_pass=None, t_r=None, transpose=False,
            memory=Memory(cachedir=None, verbose=0),
            transform_memory=Memory(cachedir=None, verbose=0), verbose=0):
        # Mask is compulsory or computed
        self.mask = mask
        self.mask_connected = mask_connected
        self.mask_opening = mask_opening
        self.mask_lower_cutoff = mask_lower_cutoff
        self.mask_upper_cutoff = mask_upper_cutoff
        self.smooth = smooth
        self.confounds = confounds
        self.detrend = detrend
        self.target_affine = target_affine
        self.target_shape = target_shape
        self.low_pass = low_pass
        self.high_pass = high_pass
        self.t_r = t_r
        self.memory = memory
        self.transform_memory = transform_memory
        self.verbose = verbose
        self.sessions = sessions
        self.transpose = transpose

    def fit(self, niimgs, y=None):
        """Compute the mask corresponding to the data

        Parameters
        ----------
        niimgs: list of filenames or NiImages
            Data on which the mask must be calculated. If this is a list,
            the affine is considered the same for all.
        """

        memory = self.memory
        if isinstance(memory, basestring):
            memory = Memory(cachedir=memory)

        # Load data (if filenames are given, load them)
        if self.verbose > 0:
            print "[%s.fit] Loading data" % self.__class__.__name__
        data = []
        for niimg in niimgs:
            data.append(utils.check_niimgs(niimg, accept_3d=True))

        # Compute the mask if not given by the user
        if self.mask is None:
            if self.verbose > 0:
                print "[%s.fit] Computing the mask" % self.__class__.__name__
            mask = memory.cache(masking.compute_session_epi_mask)(
                                data,
                                connected=self.mask_connected,
                                opening=self.mask_opening,
                                lower_cutoff=self.mask_lower_cutoff,
                                upper_cutoff=self.mask_upper_cutoff,
                                verbose=(self.verbose -1))
            self.mask_ = Nifti1Image(mask.astype(np.int), data[0].get_affine())
        else:
			self.mask_ = utils.check_niimg(self.mask)

        # If resampling is requested, resample also the mask
        # Resampling: allows the user to change the affine, the shape or both
        if self.verbose > 0:
            print "[%s.transform] Resampling mask" % self.__class__.__name__
        self.mask_ = memory.cache(resampling.resample_img)(self.mask_,
                target_affine=self.target_affine,
                target_shape=self.target_shape,
                copy=(self.target_affine is not None and
                      self.target_shape is not None))

        return self

    def transform(self, niimgs):
        data = []
	affine = None
        for index, niimg in enumerate(niimgs):
            imgs = utils.check_niimgs(niimg)
            
            if self.confounds is not None:
                data.append(self.preprocess_niimgs(niimg,
                    confounds=self.confounds[index]))
            else:
                data.append(self.preprocess_niimgs(niimg))
            if affine is None:
                affine = self.affine_
            else:
                if not np.all(affine == self.affine_):
		    raise ValueError("Affine of subject %d is different"
			    " from reference affine"
			    "\nReference affine:\n%s\n"
			    "Wrong affine:\n%s"
			    % (i_error, repr(affine), repr(self.affine_)))
        return data

{'fraction_non_alphanumeric': 0.06384234998892907, 'fraction_numerical': 0.003247472138165178, 'mean_word_length': 2.018489641345511, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4125632', 'n_tokens_mistral': 3872, 'n_tokens_neox': 3451, 'n_words': 1169}