# Configure Jupyter so figures appear in the notebook
%matplotlib inline

# Configure Jupyter to display the assigned value after an assignment
%config InteractiveShell.ast_node_interactivity='last_expr_or_assign'

# import functions from the modsim.py module
from modsim import *

"""
Explanation: Modeling and Simulation in Python
Chapter 17
Copyright 2017 Allen Downey
License: Creative Commons Attribution 4.0 International
End of explanation
"""


data = pd.read_csv('data/glucose_insulin.csv', index_col='time')

"""
Explanation: Data
We have data from Pacini and Bergman (1986), "MINMOD: a computer program to calculate insulin sensitivity and pancreatic responsivity from the frequently sampled intravenous glucose tolerance test", Computer Methods and Programs in Biomedicine, 23: 113-122..
End of explanation
"""


plot(data.glucose, 'bo', label='glucose')
decorate(xlabel='Time (min)',
         ylabel='Concentration (mg/dL)')

"""
Explanation: Here's what the glucose time series looks like.
End of explanation
"""


plot(data.insulin, 'go', label='insulin')
decorate(xlabel='Time (min)',
         ylabel='Concentration ($\mu$U/mL)')

"""
Explanation: And the insulin time series.
End of explanation
"""


subplot(2, 1, 1)
plot(data.glucose, 'bo', label='glucose')
decorate(ylabel='Concentration (mg/dL)')

subplot(2, 1, 2)
plot(data.insulin, 'go', label='insulin')
decorate(xlabel='Time (min)',
         ylabel='Concentration ($\mu$U/mL)')

savefig('figs/chap17-fig01.pdf')

"""
Explanation: For the book, I put them in a single figure, using subplot
End of explanation
"""


I = interpolate(data.insulin)

"""
Explanation: Interpolation
We have measurements of insulin concentration at discrete points in time, but we need to estimate it at intervening points.  We'll use interpolate, which takes a Series and returns a function:
The return value from interpolate is a function.
End of explanation
"""


I(7)

"""
Explanation: We can use the result, I, to estimate the insulin level at any point in time.
End of explanation
"""


t_0 = get_first_label(data)
t_end = get_last_label(data)
ts = linrange(t_0, t_end, endpoint=True)
I(ts)
type(ts)

"""
Explanation: I can also take an array of time and return an array of estimates:
End of explanation
"""


plot(data.insulin, 'go', label='insulin data')
plot(ts, I(ts), color='green', label='interpolated')

decorate(xlabel='Time (min)',
         ylabel='Concentration ($\mu$U/mL)')

savefig('figs/chap17-fig02.pdf')

"""
Explanation: Here's what the interpolated values look like.
End of explanation
"""


# Solution goes here

"""
Explanation: Exercise: Read the documentation of scipy.interpolate.interp1d.  Pass a keyword argument to interpolate to specify one of the other kinds of interpolation, and run the code again to see what it looks like.
End of explanation
"""


# Solution goes here

"""
Explanation: Exercise: Interpolate the glucose data and generate a plot, similar to the previous one, that shows the data points and the interpolated curve evaluated at the time values in ts.
End of explanation
"""


source_code(interpolate)

"""
Explanation: Under the hood
End of explanation
"""


