예제 #1
0
    def save(self):
        if self.perc_bad_voxels == None and self.file:
            import neurovault.apps.statmaps.utils as nvutils
            self.file.open()
            gzfileobj = GzipFile(filename=self.file.name,
                                 mode='rb',
                                 fileobj=self.file.file)
            nii = nb.Nifti1Image.from_file_map(
                {'image': nb.FileHolder(self.file.name, gzfileobj)})
            self.is_thresholded, ratio_bad = nvutils.is_thresholded(nii)
            self.perc_bad_voxels = ratio_bad * 100.0

        if self.brain_coverage == None and self.file:
            import neurovault.apps.statmaps.utils as nvutils
            self.file.open()
            gzfileobj = GzipFile(filename=self.file.name,
                                 mode='rb',
                                 fileobj=self.file.file)
            nii = nb.Nifti1Image.from_file_map(
                {'image': nb.FileHolder(self.file.name, gzfileobj)})
            self.not_mni, self.brain_coverage, self.perc_voxels_outside = nvutils.not_in_mni(
                nii)

        if self.map_type == self.OTHER:
            import neurovault.apps.statmaps.utils as nvutils
            self.file.open()
            gzfileobj = GzipFile(filename=self.file.name,
                                 mode='rb',
                                 fileobj=self.file.file)
            nii = nb.Nifti1Image.from_file_map(
                {'image': nb.FileHolder(self.file.name, gzfileobj)})
            self.map_type = nvutils.infer_map_type(nii)

        # Calculation of image reduced_representation and comparisons
        file_changed = False
        if self.pk is not None:
            existing = Image.objects.get(pk=self.pk)
            if existing.file != self.file:
                file_changed = True
        do_update = True if file_changed else False
        new_image = True if self.pk is None else False

        # If we have an update, delete old pkl and comparisons first before saving
        if do_update and self.collection:
            if self.reduced_representation:  # not applicable for private collections
                self.reduced_representation.delete()

                # If more than one metric is added to NeuroVault, this must also filter based on metric
                comparisons = Comparison.objects.filter(
                    Q(image1=self) | Q(image2=self))
                if comparisons:
                    comparisons.delete()
        super(BaseStatisticMap, self).save()

        # Calculate comparisons
        if do_update or new_image:
            run_voxelwise_pearson_similarity.apply_async([self.pk])

        self.file.close()
예제 #2
0
def generate_surface_image(image_pk):
    from neurovault.apps.statmaps.models import Image
    from scipy.io import loadmat
    import numpy.matlib as matlib
    from scipy.interpolate import interpn

    img = Image.objects.get(pk=image_pk)
    if img.target_template_image in ['GenericMNI', 'MNI152NLin2009cAsym'] and \
            img.data_origin == 'volume':
        img_vol = nib.load(img.file.path)
        data_vol = img_vol.get_data()
        if data_vol.ndim > 3:
            data_dim = data_vol.shape[3]  #number of time points
        else:
            data_dim = 1
        this_path = os.path.abspath(os.path.dirname(__file__))

        for hemi in ['lh', 'rh']:
            if hemi == 'lh':
                ras_coor = loadmat(os.path.abspath(os.path.join(this_path, "static", "anatomical",
                                                                "lh.avgMapping_allSub_RF_ANTs_MNI2fs.mat")))['ras']
            else:
                ras_coor = loadmat(os.path.abspath(os.path.join(this_path, "static", "anatomical",
                                                                "rh.avgMapping_allSub_RF_ANTs_MNI2fs.mat")))['ras']

            vox2ras = img_vol.get_sform()
            ras_centered = ras_coor - matlib.repmat(vox2ras[0:3, 3], ras_coor.shape[1], 1).T
            vox_coor = numpy.dot(numpy.linalg.inv(vox2ras[0:3, 0:3]), ras_centered)  # convert to voxel coordinates

            img_surf = nib.gifti.GiftiImage()
            for i in range(data_dim):
                if data_vol.ndim > 3:
                    data_curr = data_vol[:, :, :, i]
                    data_surf = interpn([range(data_vol.shape[0]), range(data_vol.shape[1]), range(data_vol.shape[2])],
                                        data_curr, vox_coor.T, 'linear')
                    data_surf_gifti = nib.gifti.GiftiDataArray(data_surf, 'NIFTI_INTENT_TIME_SERIES', 'NIFTI_TYPE_FLOAT32',
                                                               'ASCII')
                else:
                    data_curr = data_vol
                    data_surf = interpn([range(data_vol.shape[0]), range(data_vol.shape[1]), range(data_vol.shape[2])],
                                        data_curr, vox_coor.T, 'linear')
                    data_surf_gifti = nib.gifti.GiftiDataArray(data_surf, 'NIFTI_INTENT_NONE', 'NIFTI_TYPE_FLOAT32',
                                                               'ASCII')
                img_surf.add_gifti_data_array(data_surf_gifti)

            f = BytesIO()
            fmap = {'image': nib.FileHolder(fileobj=f), 'header': nib.FileHolder(fileobj=f)}
            img_surf.to_file_map(fmap)
            f.seek(0)
            content_file = ContentFile(f.read())
            if hemi == 'lh':
                img.surface_left_file.save("surface_%s_%s.gii" % (hemi, img.pk), content_file)
            else:
                img.surface_right_file.save("surface_%s_%s.gii" % (hemi, img.pk), content_file)
        img.save()
    print("Surface image generation done.")
예제 #3
0
    def clean(self, **kwargs):
        cleaned_data = super(StatisticMapForm, self).clean()
        django_file = cleaned_data.get("file")

        cleaned_data[
            "is_valid"] = True  #This will be only saved if the form will validate
        cleaned_data["tags"] = clean_tags(cleaned_data)

        if django_file and "file" not in self._errors and "hdr_file" not in self._errors:
            django_file.open()
            fileobj = StringIO(django_file.read())
            django_file.seek(0)
            gzfileobj = GzipFile(filename=django_file.name,
                                 mode='rb',
                                 fileobj=fileobj)
            nii = nb.Nifti1Image.from_file_map(
                {'image': nb.FileHolder(django_file.name, gzfileobj)})
            cleaned_data["is_thresholded"], ratio_bad = is_thresholded(nii)
            cleaned_data["perc_bad_voxels"] = ratio_bad * 100.0

            if cleaned_data["is_thresholded"] and not cleaned_data.get(
                    "ignore_file_warning") and cleaned_data.get(
                        "map_type") != "R":
                self._errors["file"] = self.error_class([
                    "This map seems to be thresholded (%.4g%% of voxels are zeros). Please use an unthresholded version of the map if possible."
                    % (cleaned_data["perc_bad_voxels"])
                ])
                if cleaned_data.get("hdr_file"):
                    self._errors["hdr_file"] = self.error_class([
                        "This map seems to be thresholded (%.4g%% of voxels are zeros). Please use an unthresholded version of the map if possible."
                        % (cleaned_data["perc_bad_voxels"])
                    ])
                self.fields[
                    "ignore_file_warning"].widget = forms.CheckboxInput()
            else:
                cleaned_data["not_mni"], cleaned_data[
                    "brain_coverage"], cleaned_data[
                        "perc_voxels_outside"] = not_in_mni(nii)
                if cleaned_data["not_mni"] and not cleaned_data.get(
                        "ignore_file_warning") and cleaned_data.get(
                            "map_type") != "R":
                    self._errors["file"] = self.error_class([
                        "This map seems not to be in the MNI space (%.4g%% of meaningful voxels are outside of the brain). Please use transform your data to MNI space."
                        % (cleaned_data["perc_voxels_outside"])
                    ])
                    if cleaned_data.get("hdr_file"):
                        self._errors["hdr_file"] = self.error_class([
                            "This map seems not to be in the MNI space (%.4g%% of meaningful voxels are outside of the brain). Please use transform your data to MNI space."
                            % (cleaned_data["perc_voxels_outside"])
                        ])
                    self.fields[
                        "ignore_file_warning"].widget = forms.CheckboxInput()

            if cleaned_data.get("map_type") == "R":
                if "not_mni" in cleaned_data:
                    del cleaned_data["not_mni"]
                if "is_thresholded" in cleaned_data:
                    del cleaned_data["is_thresholded"]

        return cleaned_data
예제 #4
0
def read_img(filename, data, benchmark, start, output_dir, bench_dir=None):

    start_time = time() - start

    print('Reading image', filename)
    # load binary data into Nibabel
    fh = nib.FileHolder(fileobj=BytesIO(data))
    im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})

    data = im.get_data()

    end_time = time() - start

    bn = os.path.basename(filename)

    bench_file = None
    if benchmark:
        bench_file = write_bench('read_img',
                                 start_time,
                                 end_time,
                                 socket.gethostname(),
                                 output_dir,
                                 bn,
                                 get_ident(),
                                 benchmark_dir=bench_dir)

    return (socket.gethostname(), filename, data, (im.affine, im.header),
            bench_file)
예제 #5
0
def get_2dimg(s3obj, axis=1, begin=1, end=1, rot=0):
    """ obtain slices of 2D images from nifti data"""
    # get the images from 3s obj
    response = s3obj.get()
    zipfile = gzip.open(response['Body'])
    iobyte = io.BytesIO(zipfile.read())
    fholder = nib.FileHolder(fileobj=iobyte)
    imgs = nib.Nifti1Image.from_file_map({'header': fholder, 'image': fholder})
    imgdata = imgs.get_fdata()
    logging.info(imgs.shape)

    # extract region of interest; slices from 'begin' to 'end' along 'axis'
    # axis = 0: x-axis (sagittal), 1: y-axis (coronal), 2: z-axis (axial)
    if axis == 0:
        imgdata = imgdata[int(begin):int(end), :, :]
    elif axis == 1:
        imgdata = imgdata[:, int(begin):int(end), :]
    elif axis == 2:
        imgdata = imgdata[:, :, int(begin):int(end)]
    imgs = []
    for j in range(imgdata.shape[axis]):
        if axis == 0:
            imgs.append(np.rot90(imgdata[j, :, :], rot))
        elif axis == 1:
            imgs.append(np.rot90(imgdata[:, j, :], rot))
        elif axis == 2:
            imgs.append(np.rot90(imgdata[:, :, j], rot))
    return np.asarray(imgs)
예제 #6
0
def s3fs_nifti_read(fname, fs=None):
    """
    Lazily reads a nifti image from S3.

    Paramters
    ---------
    fname : string
        Full path (including bucket name and extension) to the S3 location
        of the file to be read.
    fs : an s3fs.S3FileSystem class instance, optional
        A file-system to refer to. Default to create a new file-system.

    Returns
    -------
    nib.Nifti1Image class instance

    Note
    ----
    Because the image is lazily loaded, data stored in the file
    is not transferred until `get_fdata` is called.

    """
    if fs is None:
        fs = s3fs.S3FileSystem()
    with fs.open(fname) as ff:
        zz = gzip.open(ff)
        rr = zz.read()
        bb = BytesIO(rr)
        fh = nib.FileHolder(fileobj=bb)
        img = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})
    return img
예제 #7
0
def get_voxels(filename, start, args):
    """Retrieve voxel intensity of a Nifti image as a byte stream.

    Parameters
    ----------
    filename: str
        Representation of the path for the input file.

    Returns
    -------
    data : da.array
        Data of the nifti imaeg read.
    """
    start_time = time() - start

    img = None
    with open(filename, "rb") as f_in:
        fh = nib.FileHolder(fileobj=BytesIO(f_in.read()))
        img = nib.Nifti1Image.from_file_map({"header": fh, "image": fh})
    data = img.get_fdata(caching="unchanged")
    data = nib.casting.float_to_int(data, np.int16)

    end_time = time() - start

    if args.benchmark:
        benchmark(
            start_time,
            end_time,
            filename,
            args.output_dir,
            args.experiment,
            get_voxels.__name__,
        )

    return da.from_array(data)
def get_voxels(d):

    # read data into nibabel
    fh = nib.FileHolder(fileobj=BytesIO(d[1]))
    im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})

    data = im.get_data()

    return data.flatten('F')
예제 #9
0
def read_nii(filename):
    with tf.gfile.GFile(filename, 'rb') as f:
        bb = io.BytesIO(f.read())
        fh = nib.FileHolder(fileobj=bb)
        img = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})
    subject, seriesID = get_keys(filename)
    image = img.get_fdata()
    image = image[40:200, 40:200, 112:144]
    image /= 255.0
    image = np.asmatrix(image.ravel())
    return {'image': image, 'subject': subject, 'series': seriesID}
예제 #10
0
def load_volume(volume, log_file="timelog.json"):
    """
    Load volumetric data into a
    `Nibabel SpatialImage <http://nipy.org/nibabel/reference/nibabel.spatialimages.html#nibabel.spatialimages.SpatialImage>`_

    Parameters
    ----------
    volume: niimg
        Volumetric data to be loaded, can be a path to a file that nibabel can
        load, or a Nibabel SpatialImage

    Returns
    ----------
    image: Nibabel SpatialImage

    Notes
    ----------
    Originally created as part of Laminar Python [1]_ .

    References
    -----------
    .. [1] Huntenburg et al. (2017), Laminar Python: Tools for cortical
       depth-resolved analysis of high-resolution brain imaging data in
       Python. DOI: 10.3897/rio.3.e12346
    """  # noqa

    # if input is a filename, try to load it
    # python 2 version if isinstance(volume, basestring):

    if isinstance(volume, str):
        start = time.time()
        # importing nifti files
        # image = nb.load(volume) # disable lazy-load
        # Read from file instead
        with open(volume, "rb") as in_file:
            # fh = nb.FileHolder(fileobj=GzipFile(fileobj=BytesIO(in_file.read())))
            fh = nb.FileHolder(fileobj=BytesIO(
                in_file.read()))  # read uncompressed file
            image = nb.Nifti1Image.from_file_map({"header": fh, "image": fh})
        end = time.time()

        caller_function = str(inspect.stack()[1].function)
        time_log(log_file, caller_function, "read", volume, start, end)
    # if volume is already a nibabel object
    elif isinstance(volume, nb.spatialimages.SpatialImage):
        image = volume
    else:
        raise ValueError('Input volume must be a either a path to a file in a '
                         'format that Nibabel can load, or a nibabel'
                         'SpatialImage.')

    return image
예제 #11
0
def get_2dimg_cent(s3obj, axis=1, nslices=-1, rot=0):
    """ obtain central slices of 2D images from nifti data"""
    # get the images from 3s obj
    iobyte = io.BytesIO(gzip.open(s3obj.get()['Body']).read())
    fholder = nib.FileHolder(fileobj=iobyte)
    imgs = nib.Nifti1Image.from_file_map({'header': fholder, 'image': fholder})
    header = imgs.header
    imgdata = imgs.get_fdata()
    logging.info(imgs.shape)

    # extract region of interest; slices from 'begin' to 'end' along 'axis'
    # axis = 0: x-axis (sagittal), 1: y-axis (coronal), 2: z-axis (axial)
    # in header['dim'] 1: x-axis, 2: y- axis, 3: z-axis
    begin = 0
    end = header['dim'][axis + 1] - 1
    if nslices != -1:
        nslices /= 2
        middle = header['dim'][axis + 1] / 2
        begin = middle - nslices
        end = middle + nslices
    if begin < 0:
        begin = 0
    if end >= header['dim'][axis + 1]:
        end = header['dim'][axis + 1] - 1
    resx = header['pixdim'][2]
    resy = header['pixdim'][3]
    # get the slices
    logging.info("Slice range: %i to %i", begin, end)
    if axis == 0:
        imgdata = imgdata[int(begin):int(end), :, :]
    elif axis == 1:
        imgdata = imgdata[:, int(begin):int(end), :]
        resx = header['pixdim'][1]
        resy = header['pixdim'][3]
    elif axis == 2:
        imgdata = imgdata[:, :, int(begin):int(end)]
        resx = header['pixdim'][1]
        resy = header['pixdim'][2]
    imgs = []
    for j in range(imgdata.shape[axis]):
        if axis == 0:
            imgs.append(np.rot90(imgdata[j, :, :], rot))
        elif axis == 1:
            imgs.append(np.rot90(imgdata[:, j, :], rot))
        elif axis == 2:
            imgs.append(np.rot90(imgdata[:, :, j], rot))
    return np.asarray(imgs), [resx, resy]
def read_img(filename, data, benchmark, start, output_dir):

    start_time = time() - start

    # load binary data into Nibabel
    fh = nib.FileHolder(fileobj=BytesIO(data))
    im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})

    data = im.get_data()

    end_time = time() - start

    bn = os.path.basename(filename)

    if benchmark:
        write_bench('read_img', start_time, end_time, socket.gethostname(),
                    output_dir, bn)

    return (filename, data, (im.affine, im.header))
예제 #13
0
def save_segmented(d, assignments, out):
    # read data into nibabel
    fh = nib.FileHolder(fileobj=BytesIO(d[1]))
    im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})

    data = im.get_data()

    assigned_class = [c[0] for c in assignments]

    for i in range(0, len(assignments)):
        assigned_voxels = list(set(assignments[i][1]))
        data[np.where(np.isin(data, assigned_voxels))] = assigned_class[i]

    im_seg = nib.Nifti1Image(data, im.affine)

    # save segmented image
    output_file = op.join(out, 'seg-' + op.basename(d[0]))
    nib.save(im_seg, output_file)

    return (output_file, "SAVED")
예제 #14
0
def read_img(filename, data, benchmark, start, bench_dir=None):
    """Convert image in-memory binary data into Numpy array.
    For in-memory Spark only.

    Keyword arguments:
    filename -- filename for which data belongs to
    data -- binary image data
    benchmark -- boolean value that specifies whether to benchmark the task
    start -- start time of the driver (in seconds)
    benchmark_dir -- benchmark directory required if benchmarking is requested.
                     (default None)

    Returns: Tuple containing image data and metadata
    """
    start_time = time() - start

    print('Reading image')
    # load binary data into Nibabel
    if data is not None:
        fh = nib.FileHolder(fileobj=BytesIO(data))
        im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})
    else:
        im = nib.load(filename)

    data = np.asanyarray(im.dataobj)

    end_time = time() - start

    bn = os.path.basename(filename)

    bench_file = None
    if benchmark:
        bench_file = write_bench('load_img',
                                 start_time,
                                 end_time,
                                 bn,
                                 os.getpid(),
                                 benchmark_dir=bench_dir)

    return (os.getpid(), filename, im, bench_file)
예제 #15
0
def read_img(filename, start, args):
    """Read a Nifti image as a byte stream.

    Parameters
    ----------
    filename: str
        Representation of the path for the input file.

    Returns
    -------
    filename : str
        Representation of the path for the input file.
    data : np.array
        Data of the nifti imaeg read.
    (img.affine, img.header) : (np.array, np.array)
        Affine and header of the nifti image read.
    """
    start_time = time() - start

    img = None
    with open(filename, "rb") as f_in:
        fh = nib.FileHolder(fileobj=BytesIO(f_in.read()))
        img = nib.Nifti1Image.from_file_map({"header": fh, "image": fh})
    data = img.get_fdata(caching="unchanged")
    data = nib.casting.float_to_int(data, np.int16)

    end_time = time() - start

    if args.benchmark:
        benchmark(
            start_time,
            end_time,
            filename,
            args.output_dir,
            args.experiment,
            read_img.__name__,
        )

    return filename, data, (img.affine, img.header)
    def load_nifti(self, base64str, is_zipped):
        """
        Load base64 encoded string read from uploaded file upload into array.
        Also crops and flips the resulting image.

        :param str base64str: base64 encoded string (i.e. the uploaded file)
        :param boolean is_zipped: if the file is zipped (i.e. if the uploaded file name ends with '.gz')
        :return: the nifti image as numpy array:
            <li> 1. dimension: image row
            <li> 2. dimension: image column
            <li> 3. dimension: image depth
            <li> 4. dimension: color channels (should be 1, because of monochrome gray scan)
        :rtype: numpy.ndarray
        """

        # x: sag
        # y: cor
        # z: axi

        x_range_from = 10
        x_range_to = 110
        y_range_from = 13
        y_range_to = 133
        z_range_from = 5
        z_range_to = 105

        if debug: print('Called load_nifti().')

        img_arr = np.zeros(
            (z_range_to - z_range_from, x_range_to - x_range_from,
             y_range_to - y_range_from, 1),
            dtype=np.float32)  # z×x×y×1; avoid 64bit types

        base64_bytes = base64str.encode("ascii")
        raw_bytes = base64.b64decode(base64_bytes)
        if is_zipped:
            if debug: print("Unzipping...")
            nifti_bytes = gzip.decompress(raw_bytes)
        else:
            if debug: print("Not unzipping...")
            nifti_bytes = raw_bytes
        inputstream = BytesIO(nifti_bytes)
        file_holder = nib.FileHolder(fileobj=inputstream)

        img = nib.Nifti1Image.from_file_map({
            'header': file_holder,
            'image': file_holder
        })
        assert (img.shape == (121, 145, 121))
        if debug:
            print("original img.shape:")
            print(img.shape)
        img = img.get_fdata()[x_range_from:x_range_to, y_range_from:y_range_to,
                              z_range_from:z_range_to]
        inputstream.close()
        img = np.transpose(
            img, (2, 0, 1)
        )  # reorder dimensions to match coronal view z*x*y in MRIcron etc.
        img = np.flip(img)  # flip all positions
        if debug:
            print("cropped img.shape: ")
            print(img.shape)
        img_arr[:, :, :, 0] = np.nan_to_num(
            img)  # orientation: axial,sagittal,coronal,colorchannel

        print("Successfully loaded uploaded nifti.")
        self.uploaded_bg_img = img_arr
        return img_arr
import os
from gzip import GzipFile

import django
import nibabel as nb

import neurovault.apps.statmaps.utils as nvutils
from neurovault.apps.statmaps.models import StatisticMap, BaseStatisticMap

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "neurovault.settings")
django.setup()

for image in StatisticMap.objects.filter(map_type=BaseStatisticMap.OTHER):
    image.file.open()
    gzfileobj = GzipFile(filename=image.file.name,
                         mode='rb',
                         fileobj=image.file.file)
    nii = nb.Nifti1Image.from_file_map(
        {'image': nb.FileHolder(image.file.name, gzfileobj)})
    map_type = nvutils.infer_map_type(nii)
    if map_type != BaseStatisticMap.OTHER:
        print "changed type of %s to %s" % (image.get_absolute_url(), map_type)
        image.map_type = map_type
        image.save()
    image.file.close()
예제 #18
0
파일: binarize_spark.py 프로젝트: gkiar/sim
def get_data(x):
    fh = nib.FileHolder(fileobj=GzipFile(fileobj=BytesIO(x[1])))
    im = nib.Nifti1Image.from_file_map({'header': fh, 'image': fh})
    return (x[0], (im.affine, im.get_data()))
예제 #19
0
def generate_surface_image(image_pk):
    from neurovault.apps.statmaps.models import Image
    from scipy.io import loadmat
    from scipy.interpolate import interpn

    img = Image.objects.get(pk=image_pk)
    if img.target_template_image in ['GenericMNI', 'MNI152NLin2009cAsym'] and \
            img.data_origin == 'volume':
        img_vol = nib.load(img.file.path)
        data_vol = img_vol.get_data()
        if data_vol.ndim > 3:
            data_vol = data_vol[:, :, :, 0]  #number of time points
        this_path = os.path.abspath(os.path.dirname(__file__))

        for hemi in ['lh', 'rh']:
            ras_coor = loadmat(
                os.path.abspath(
                    os.path.join(
                        this_path, "static", "anatomical",
                        "%s.avgMapping_allSub_RF_ANTs_MNI2fs.mat" %
                        hemi)))['ras']

            vox_coor = nib.affines.apply_affine(
                numpy.linalg.inv(img_vol.affine), ras_coor.T).T
            img_surf = nib.gifti.GiftiImage()

            if img.polymorphic_ctype.model == 'atlas' or (hasattr(
                    img, 'map_type') and img.map_type in ['Pa', 'R']):
                method = 'nearest'
            else:
                method = 'linear'

            data_surf = interpn(points=[
                range(data_vol.shape[0]),
                range(data_vol.shape[1]),
                range(data_vol.shape[2])
            ],
                                values=data_vol,
                                xi=vox_coor.T,
                                method=method,
                                bounds_error=False,
                                fill_value=0)
            # without turning nan's to zeros Connectome Workbench behaves weird
            data_surf[numpy.isnan(data_surf)] = 0

            # ASCII is the only encoding that produces outputs compatible with Connectome Workbench
            data_surf_gifti = nib.gifti.GiftiDataArray(data_surf,
                                                       'NIFTI_INTENT_NONE',
                                                       'NIFTI_TYPE_FLOAT32',
                                                       'ASCII')
            img_surf.add_gifti_data_array(data_surf_gifti)
            img_surf.meta.data.insert(
                0,
                nib.gifti.GiftiNVPairs('AnatomicalStructurePrimary', {
                    'lh': 'CortexLeft',
                    'rh': 'CortexRight'
                }[hemi]))

            f = BytesIO()
            fmap = {
                'image': nib.FileHolder(fileobj=f),
                'header': nib.FileHolder(fileobj=f)
            }
            img_surf.to_file_map(fmap)
            f.seek(0)
            content_file = ContentFile(f.read())
            if hemi == 'lh':
                img.surface_left_file.save(
                    "%s.%s.func.gii" % (img.pk, {
                        'lh': 'L',
                        'rh': 'R'
                    }[hemi]), content_file)
            else:
                img.surface_right_file.save(
                    "%s.%s.func.gii" % (img.pk, {
                        'lh': 'L',
                        'rh': 'R'
                    }[hemi]), content_file)
        img.save()
        print("Surface image generation done.")
예제 #20
0
    def clean_and_validate(self, cleaned_data):
        file = cleaned_data.get('file')

        if file:
            # check extension of the data file
            _, fname, ext = split_filename(file.name)
            if not ext.lower() in [".nii.gz", ".nii", ".img"]:
                self._errors["file"] = self.error_class(
                    ["Doesn't have proper extension"])
                del cleaned_data["file"]
                return cleaned_data

            # prepare file to loading into memory
            file.open()
            fileobj = file.file
            if file.name.lower().endswith(".gz"):
                fileobj = GzipFile(filename=file.name,
                                   mode='rb',
                                   fileobj=fileobj)

            file_map = {'image': nb.FileHolder(file.name, fileobj)}
            try:
                tmp_dir = tempfile.mkdtemp()
                if ext.lower() == ".img":
                    hdr_file = cleaned_data.get('hdr_file')
                    if hdr_file:
                        # check extension of the hdr file
                        _, _, hdr_ext = split_filename(hdr_file.name)
                        if not hdr_ext.lower() in [".hdr"]:
                            self._errors["hdr_file"] = self.error_class(
                                ["Doesn't have proper extension"])
                            del cleaned_data["hdr_file"]
                            return cleaned_data
                        else:
                            hdr_file.open()
                            file_map["header"] = nb.FileHolder(
                                hdr_file.name, hdr_file.file)
                    else:
                        self._errors["hdr_file"] = self.error_class(
                            [".img file requires .hdr file"])
                        del cleaned_data["hdr_file"]
                        return cleaned_data

                # check if it is really nifti
                try:
                    print file_map
                    if "header" in file_map:
                        nii = nb.Nifti1Pair.from_file_map(file_map)
                    else:
                        nii = nb.Nifti1Image.from_file_map(file_map)
                except Exception as e:
                    raise

                # detect AFNI 4D files and prepare 3D slices
                if nii is not None and detect_4D(nii):
                    self.afni_subbricks = split_4D_to_3D(nii, tmp_dir=tmp_dir)
                else:
                    squeezable_dimensions = len(
                        filter(lambda a: a not in [0, 1], nii.shape))

                    if squeezable_dimensions != 3:
                        self._errors["file"] = self.error_class([
                            "4D files are not supported.\n "
                            "If it's multiple maps in one "
                            "file please split them and "
                            "upload separately"
                        ])
                        del cleaned_data["file"]
                        return cleaned_data

                    # convert to nii.gz if needed
                    if (ext.lower() != ".nii.gz"
                            or squeezable_dimensions < len(nii.shape)):
                        # convert pseudo 4D to 3D
                        if squeezable_dimensions < len(nii.shape):
                            new_data = np.squeeze(nii.get_data())
                            nii = nb.Nifti1Image(new_data, nii.get_affine(),
                                                 nii.get_header())

                        # Papaya does not handle float64, but by converting
                        # files we loose precision
                        # if nii.get_data_dtype() == np.float64:
                        # ii.set_data_dtype(np.float32)
                        new_name = fname + ".nii.gz"
                        nii_tmp = os.path.join(tmp_dir, new_name)
                        nb.save(nii, nii_tmp)

                        print "updating file in cleaned_data"

                        cleaned_data['file'] = memory_uploadfile(
                            nii_tmp, new_name, cleaned_data['file'])
            finally:
                try:
                    if self.afni_subbricks:
                        # keep temp dir for AFNI slicing
                        self.afni_tmp = tmp_dir
                    else:
                        print "removing %s" % tmp_dir
                        shutil.rmtree(tmp_dir)
                except OSError as exc:
                    if exc.errno != 2:  # code 2 - no such file or directory
                        raise  # re-raise exception
        elif not getattr(self, 'partial', False):
            # Skip validation error if this is a partial update from the API
            raise ValidationError("Couldn't read uploaded file")

        return cleaned_data
예제 #21
0
            _, fname, ext = split_filename(file.name)
            if not ext.lower() in [".nii.gz", ".nii", ".img"]:
                self._errors["file"] = self.error_class(
                    ["Doesn't have proper extension"]
                )
                del cleaned_data["file"]
                return cleaned_data

            # prepare file to loading into memory
            file.open()
            fileobj = file.file
            if file.name.lower().endswith(".gz"):
                fileobj = GzipFile(filename=file.name, mode='rb',
                                   fileobj=fileobj)

            file_map = {'image': nb.FileHolder(file.name, fileobj)}
            try:
                tmp_dir = tempfile.mkdtemp()
                if ext.lower() == ".img":
                    hdr_file = cleaned_data.get('hdr_file')
                    if hdr_file:
                        # check extension of the hdr file
                        _, _, hdr_ext = split_filename(hdr_file.name)
                        if not hdr_ext.lower() in [".hdr"]:
                            self._errors["hdr_file"] = self.error_class(
                                ["Doesn't have proper extension"])
                            del cleaned_data["hdr_file"]
                            return cleaned_data
                        else:
                            hdr_file.open()
                            file_map["header"] = nb.FileHolder(hdr_file.name,