a = 2

a += 2

print(a)

"""
Explanation: Welcome to Jupyter Notebook
This is a Jupyter Notebook. It works just like python console, but you can freely go back and forth and reexecute pieces (cells) of code.
To run code press Shift+Enter
End of explanation
"""


!ls -al

"""
Explanation: I can do to the second cell and run it again and again making "a" bigger and bigger.
You can always reset the "state" of the notebook by doing "Kernel->Restart". You can also rerun all of the cells from the top, by doing "Cell->Run all". Try it now.
Jupyter allows you to run any bash command by using the exclamation mark "!":
End of explanation
"""


name = "Chris"
text = "My name is " + name
!echo "{text}" > test.txt
!cat test.txt

"""
Explanation: You can use variables defined in python in the bash calls using brackets "{}":
End of explanation
"""


int?

"""
Explanation: It's easy to get help in the notebook - just follow a command with question mark '?'
End of explanation
"""


import pylab as plt
import seaborn as sns

"""
Explanation: Plotting
To plot data in python we are going to use matplotlib and seaborn.
End of explanation
"""


import numpy as np

random_data = np.random.rand(10,10)
plt.plot(random_data)

"""
Explanation: We'll nead numpy for generating some random data
End of explanation
"""


%matplotlib inline
plt.plot(random_data)

"""
Explanation: Where is the plot?!? We need to explicitly tell notebookto put it inline
End of explanation
"""


plt.scatter(random_data[0,:], random_data[1,:])

"""
Explanation: We can also plot a scatterplot
End of explanation
"""


sns.heatmap(random_data)

"""
Explanation: We can also plot an array:
End of explanation
"""


print('shape of random_data:',random_data.shape)
print('shape of random_data.ravel():',random_data.ravel().shape)
sns.distplot(random_data.ravel())

"""
Explanation: Histograms
End of explanation
"""


import nibabel as nb
import os

datadir="../../../data/ds003"
if not os.path.exists(datadir):
    # custom location for Russ's laptop
    datadir='/Users/poldrack/data_unsynced/ds003'
boldfile=os.path.join(datadir,"sub001/BOLD/task001_run001/bold.nii.gz")
nii = nb.load(boldfile)

"""
Explanation: Exercise: sample data from a normal distribution and plot it distribution
Reading NIFTI files using nibabel
Nibabel is librabry for reading and writing to various neuroimaging data formats
End of explanation
"""


nii.shape

header = nii.get_header()
header.get_xyzt_units()

nii.get_affine()

"""
Explanation: We can read shape and headers of a nifti file without loading it into memory
End of explanation
"""


data = nii.get_data()
print(data.shape)
sns.set_style("white")
plt.imshow(data[:,:,10,1])

"""
Explanation: We can also get the data:
End of explanation
"""


new_nii = nb.Nifti1Image(np.random.rand(*(nii.shape[:-1])), nii.get_affine())
new_nii.to_filename("/tmp/test.nii.gz")
print(new_nii.shape)

!fslview /tmp/test.nii.gz

"""
Explanation: We can create new files
End of explanation
"""


import nilearn.plotting, nilearn.image

nilearn.plotting.plot_epi(new_nii)

nilearn.plotting.plot_epi(nii)

nilearn.plotting.plot_epi(nilearn.image.index_img(nii,0))

nilearn.plotting.plot_epi(nilearn.image.mean_img(nii))

nilearn.plotting.plot_anat(os.path.join(datadir,"sub001/anatomy/inplane.nii.gz"))

"""
Explanation: Task: load an anatomical scan from "../../../data/ds003/sub001/anatomy/inplane.nii.gz" threshold it and save the data back to a file in your home directory
Image manipulation using nilearn
nilearn is a python package for doing machine learning in neuroimaging. We will primarly use it to plot and manipulate images
End of explanation
"""


from nipype.caching import Memory
from nipype.interfaces import fsl
mem = Memory(base_dir='.')


fslmean = mem.cache(fsl.maths.MeanImage)
fslmean_results = fslmean(in_file=os.path.join(datadir,"sub001/BOLD/task001_run001/bold.nii.gz"))
fslmean_results.outputs

nilearn.plotting.plot_epi(fslmean_results.outputs.out_file)

"""
Explanation: Exercise: explore plotting options - could you plot the anatomical image as a series of axial slices?
Nipype
Nipype is a python library for interacting tith various neuroimaging programs. It's primarly used for constructing workflows taht are later executed on many subjects on a cluster. For this workshop we will primarly use it to cache results or commandlines
End of explanation
"""


fslmean_results = fslmean(in_file=os.path.join(datadir,"sub001/BOLD/task001_run001/bold.nii.gz"))
fslmean_results.outputs

"""
Explanation: Notice that if we run it again nothing get's recalculated - nipype will be smart enough to use the cache
End of explanation
"""


fslmean_results = fslmean(in_file=os.path.join(datadir,"sub003/BOLD/task001_run001/bold.nii.gz"))
fslmean_results.outputs

"""
Explanation: But if we change the inputs new calculation will be triggered
End of explanation
"""


