!pip install cottoncandy nibabel

"""
Explanation: Using cottoncandy to access OpenNeuro data from AWS S3
This examples shows how to use cottoncandy to access data from OpenNeuro.
To find out more about cottoncandy, checkout our GitHub repo: 
https://github.com/gallantlab/cottoncandy

Contributed by:
Anwar O Nunez-Elizalde (Aug, 2018)
End of explanation
"""


def download_nifti(object_name, cci):
    '''Use cottoncandy to download a nifti image from the OpenNeuro S3 database

    Parameters
    ----------
    object_name : str
    The name of the image to download
    cci : object
    A cottoncandy instance

    Returns
    -------
    nifti_image : nibabel.Nifti1Image

    Example
    -------
    >>> import cottoncandy as cc
    >>> cci = cc.get_interface('openneuro', ACCESS_KEY='FAKEAC', SECRET_KEY='FAKESK', endpoint_url='https://s3.amazonaws.com')
    >>> nifti_image = download_nifti('ds000255/ds000255_R1.0.0/uncompressed/sub-02/ses-02/func/sub-02_ses-02_task-viewFigure_run-06_bold.nii.gz', cci)
    >>> nifti_image.get_data() # return numpy array

    See
    ---
    https://github.com/gallantlab/cottoncandy
    '''
  
    import cottoncandy as cc
    cci.set_bucket('openneuro.org')
    data_stream = cci.download_stream(object_name)
    # Uncompress the data
    uncompressed_data = cc.utils.GzipInputStream(data_stream.content)

    try:
        from cStringIO import StringIO
    except ImportError:
        from io import BytesIO as StringIO

    # make a file-object
    container = StringIO()
    container.write(uncompressed_data.read())
    container.seek(0)

    import nibabel as nib

    # make an image container
    nifti_map = nib.Nifti1Image.make_file_map()
    nifti_map['image'].fileobj = container

    # make a nifti image
    nii = nib.Nifti1Image.from_file_map(nifti_map)
    return nii

"""
Explanation: A function to download nifti images as nibabel objects
We will describe each step in the function in the rest of the document.
End of explanation
"""


ACCESSKEY = 'FAKEAK' 
SECRETKEY = 'FAKESK'

import cottoncandy as cc
cci = cc.get_interface('openneuro.org', ACCESS_KEY=ACCESSKEY, SECRET_KEY=SECRETKEY, endpoint_url='https://s3.amazonaws.com')

"""
Explanation: Setting up the cottoncandy connection
In order to run this example, you will need to enter your AWS keys below
End of explanation
"""


# Get the data stream
nifti_object_name = 'ds000255/sub-02/ses-02/func/sub-02_ses-02_task-viewFigure_run-06_bold.nii.gz'
data_stream = cci.download_stream(nifti_object_name)
# This is a GZIP Nifti so we need to uncompress it
uncompressed_data = cc.utils.GzipInputStream(data_stream.content)

"""
Explanation: Downloading and uncompressing the data
End of explanation
"""


try:
    from cStringIO import StringIO
except ImportError:
    from io import BytesIO as StringIO
# make a file-object
container = StringIO()
container.write(uncompressed_data.read())
container.seek(0)

"""
Explanation: Creating a file object
End of explanation
"""


import nibabel as nib

# make an image container
nifti_map = nib.Nifti1Image.make_file_map()
nifti_map['image'].fileobj = container
# make a nifti image
nii = nib.Nifti1Image.from_file_map(nifti_map)

# Get the data!
arr = nii.get_data().T
print(arr.shape)

"""
Explanation: Creating a nibabel image
End of explanation
"""


import matplotlib.pyplot as plt
plt.matshow(arr[100,15], cmap='inferno')
plt.grid(False)
__ = plt.title('Sample slice from image', fontsize=30)

tsnr = arr.mean(0)/arr.std(0)
plt.matshow(tsnr[15], cmap='inferno')
plt.grid(False)
__ = plt.title('Temporal SNR image', fontsize=30)

"""
Explanation: Plotting the data
End of explanation
"""


cci = cc.get_interface('openneuro.org', ACCESS_KEY=ACCESSKEY, SECRET_KEY=SECRETKEY, endpoint_url='https://s3.amazonaws.com')
dirs = cci.lsdir()
print('Sample datasets:\n%s'%', '.join(dirs[-10:]))

"""
Explanation: Iterating through multiple nifti images from OpenNeuro S3 bucket
End of explanation
"""


cci.lsdir('ds000255')

"""
Explanation: Explore one dataset
End of explanation
"""


from pprint import pprint
# print metadata from JSON file
pprint(cci.download_json('ds000255/dataset_description.json'))

# print the 1000 characters in the readm
print(cci.download_object('ds000255/README')[:1000]) 

# list the contents of the functional directory for sub02 in session 02
cci.lsdir('ds000255/sub-02/ses-02/func/')

"""
Explanation: Information about the dataset
End of explanation
"""


cci.search('ds000255/sub-02/ses-02/func/*.nii.gz')
# note that the beggining of the file name is cut off in the printed output. 
# this occurs because the object names are very long. 

nifti_files = cci.glob('ds000255/sub-02/ses-02/func/*.nii.gz')
print(nifti_files[0]) # the full object name

"""
Explanation: Let's find all the nifti images for subject 02 session 02
End of explanation
"""


for fl in nifti_files[:5]:
    print('Working on: %s'%fl)

    # Use the function defined at the beginning
    nii = download_nifti(fl, cci)

    arr = nii.get_data().T
    tsnr = arr.mean(0)/arr.std(0)
    plt.matshow(tsnr[15], cmap='inferno')
    plt.grid(False)

    description = fl.split('/')[-1]
    __ = plt.title('Temporal SNR image:\n%s'%description, fontsize=20)

"""
Explanation: Compute temporal SNR images for individual nifti runs
End of explanation
"""


