Visualize generated scenarios¶

(from the /llm/generate/scenario endpoint)

Demonstrate a generated scenario (curl)¶

In [12]:
# %%sh

# curl -X 'POST' \
#   'http://localhost:8001/llm/generate/scenario' \
#   -H 'accept: application/json' \
#   -H 'Content-Type: application/json' \
#   -d '{
#   "query": "A healthy patient."
# }'

Generate using the pfun-cma-model CLI¶

In [13]:
# !pfun-cma-model generate-scenario

Load the scenario¶

In [14]:
import json
from pathlib import Path
import pandas as pd

response_fpath = Path('../../results/generated-responses/response_1760175858463.json')

response_json = json.loads(response_fpath.read_text())

response_json
Out[14]:
{'qualitative_description': 'This individual leads a very structured and healthy lifestyle, which contributes to excellent glycemic control. They maintain a balanced diet with consistent carbohydrate intake at each meal, engage in moderate physical activity daily, such as a brisk walk after dinner, and prioritize getting 7-8 hours of quality sleep each night. Their stress levels are low, and they live in a temperate climate with consistent daylight hours throughout the year. As a result, their blood glucose levels are generally stable and predictable.',
 'parameters': {'d': 0, 'taup': 1, 'taug': 1, 'B': 0.05, 'Cm': 0, 'toff': 0},
 'sample_solutions': [{'t': 0,
   'c': 0.0830452722,
   'm': 0.8535533906,
   'a': 0.2507233447,
   'I_S': 0.1529527985,
   'I_E': 0.0383488372,
   'L': 0,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 1.0434782609,
   'c': 0.0380090513,
   'm': 0.9358301507,
   'a': 0.2539293579,
   'I_S': 0.0835026721,
   'I_E': 0.0212037799,
   'L': 3e-08,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 2.0869565217,
   'c': 0.0214209099,
   'm': 0.98574969,
   'a': 0.2627732222,
   'I_S': 0.0388959914,
   'I_E': 0.010220825,
   'L': 1.14478e-05,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 3.1304347826,
   'c': 0.018137561,
   'm': 0.9970919474,
   'a': 0.2807421255,
   'I_S': 0.028649172,
   'I_E': 0.0080430294,
   'L': 0.0008732045,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 4.1739130435,
   'c': 0.0406263784,
   'm': 0.9241524904,
   'a': 0.3102280959,
   'I_S': 0.0942280173,
   'I_E': 0.0292321784,
   'L': 0.0182225189,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 5.2173913043,
   'c': 0.3938120152,
   'm': 0.5992820998,
   'a': 0.3490666056,
   'I_S': 0.3281195997,
   'I_E': 0.1145355949,
   'L': 0.1325418824,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 6.2608695652,
   'c': 0.9279522878,
   'm': 0.1703963935,
   'a': 0.4056274734,
   'I_S': 0.6212864721,
   'I_E': 0.252010862,
   'L': 0.4097470471,
   'g_0': 0.1,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3,
   'is_meal': False},
  {'t': 7.3043478261,
   'c': 0.990231427,
   'm': 0.0183183028,
   'a': 0.4707866406,
   'I_S': 0.7544780181,
   'I_E': 0.3551981715,
   'L': 0.7051652291,
   'g_0': 0.8497368405,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 1.0497368405,
   'is_meal': True},
  {'t': 8.347826087,
   'c': 0.9453827912,
   'm': 0.0007943753,
   'a': 0.5408364261,
   'I_S': 0.781791414,
   'I_E': 0.4228212743,
   'L': 0.8892608874,
   'g_0': 0.4417664486,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.6417664486,
   'is_meal': False},
  {'t': 9.3913043478,
   'c': 0.8959669925,
   'm': 1.08762e-05,
   'a': 0.611056308,
   'I_S': 0.7939170419,
   'I_E': 0.4851280164,
   'L': 0.9710630727,
   'g_0': 0.1755985361,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3755985361,
   'is_meal': False},
  {'t': 10.4347826087,
   'c': 0.8468895341,
   'm': 1.67e-08,
   'a': 0.6741481839,
   'I_S': 0.8052153909,
   'I_E': 0.5428344935,
   'L': 0.9962487446,
   'g_0': 0.1205483507,
   'g_1': 0.1,
   'g_2': 0.1,
   'G': 0.3205483507,
   'is_meal': False},
  {'t': 11.4782608696,
   'c': 0.7978302583,
   'm': 0,
   'a': 0.7213867602,
   'I_S': 0.8164990406,
   'I_E': 0.5890115976,
   'L': 0.999953688,
   'g_0': 0.1066890291,
   'g_1': 0.9165036625,
   'g_2': 0.1,
   'G': 1.1231926916,
   'is_meal': True},
  {'t': 12.5217391304,
   'c': 0.7495150179,
   'm': 0,
   'a': 0.7433882267,
   'I_S': 0.8276115459,
   'I_E': 0.6152366795,
   'L': 0.999953688,
   'g_0': 0.1025138173,
   'g_1': 0.333193076,
   'g_2': 0.1,
   'G': 0.5357068932,
   'is_meal': False},
  {'t': 13.5652173913,
   'c': 0.7021980408,
   'm': 1.8e-09,
   'a': 0.7319539205,
   'I_S': 0.8384944488,
   'I_E': 0.6137392992,
   'L': 0.9962487446,
   'g_0': 0.1010632036,
   'g_1': 0.1555741319,
   'g_2': 0.1,
   'G': 0.3566373354,
   'is_meal': False},
  {'t': 14.6086956522,
   'c': 0.655778862,
   'm': 6.35e-08,
   'a': 0.6828954289,
   'I_S': 0.8491708001,
   'I_E': 0.5798948577,
   'L': 0.9710630727,
   'g_0': 0.1004971256,
   'g_1': 0.1165474896,
   'g_2': 0.1,
   'G': 0.3170446152,
   'is_meal': False},
  {'t': 15.652173913,
   'c': 0.6109701511,
   'm': 9.8731e-06,
   'a': 0.5990683435,
   'I_S': 0.8594672884,
   'I_E': 0.5148796447,
   'L': 0.8892608874,
   'g_0': 0.100253301,
   'g_1': 0.1059282822,
   'g_2': 0.1,
   'G': 0.3061815832,
   'is_meal': False},
  {'t': 16.6956521739,
   'c': 0.5652728153,
   'm': 0.0012420615,
   'a': 0.4927579526,
   'I_S': 0.8687824528,
   'I_E': 0.4280994627,
   'L': 0.7051652291,
   'g_0': 0.1001385657,
   'g_1': 0.1024473713,
   'g_2': 0.1,
   'G': 0.302585937,
   'is_meal': False},
  {'t': 17.7391304348,
   'c': 0.4727659974,
   'm': 0.0253236297,
   'a': 0.3862959294,
   'I_S': 0.8666998998,
   'I_E': 0.3348026433,
   'L': 0.4097470471,
   'g_0': 0.1000800258,
   'g_1': 0.1011226915,
   'g_2': 0.6652589215,
   'G': 0.8664616388,
   'is_meal': True},
  {'t': 18.7826086957,
   'c': 0.2936575613,
   'm': 0.1473735678,
   'a': 0.3061460908,
   'I_S': 0.7895064001,
   'I_E': 0.2417042981,
   'L': 0.1325418824,
   'g_0': 0.1000482904,
   'g_1': 0.1005590015,
   'g_2': 0.5310349728,
   'G': 0.7316422646,
   'is_meal': False},
  {'t': 19.8260869565,
   'c': 0.1823035565,
   'm': 0.3300231124,
   'a': 0.2652540915,
   'I_S': 0.637947763,
   'I_E': 0.1692182543,
   'L': 0.0182225189,
   'g_0': 0.1000297827,
   'g_1': 0.100292864,
   'g_2': 0.20462541,
   'G': 0.4049480567,
   'is_meal': False},
  {'t': 20.8695652174,
   'c': 0.1327959552,
   'm': 0.4816654608,
   'a': 0.2524778631,
   'I_S': 0.5022414334,
   'I_E': 0.1268048439,
   'L': 0.0008732045,
   'g_0': 0.1000184894,
   'g_1': 0.1001579958,
   'g_2': 0.1302813849,
   'G': 0.3304578701,
   'is_meal': False},
  {'t': 21.9130434783,
   'c': 0.0873966752,
   'm': 0.6183609732,
   'a': 0.2502021979,
   'I_S': 0.3800886207,
   'I_E': 0.0950990083,
   'L': 1.14478e-05,
   'g_0': 0.1000116861,
   'g_1': 0.1000883661,
   'g_2': 0.1103485482,
   'G': 0.3104486004,
   'is_meal': False},
  {'t': 22.9565217391,
   'c': 0.046089926,
   'm': 0.7450550414,
   'a': 0.2500020598,
   'I_S': 0.2666959268,
   'I_E': 0.0666745311,
   'L': 3e-08,
   'g_0': 0.1000075448,
   'g_1': 0.1000512318,
   'g_2': 0.1040296155,
   'G': 0.3040883921,
   'is_meal': False},
  {'t': 24,
   'c': 0.0202182535,
   'm': 0.8535533906,
   'a': 0.2499990113,
   'I_S': 0.1674030129,
   'I_E': 0.0418505877,
   'L': 0,
   'g_0': 0.1000049613,
   'g_1': 0.1000306209,
   'g_2': 0.1017335231,
   'G': 0.3017691052,
   'is_meal': False}],
 'causal_explanation': [{'action': 'Ate balanced meals with consistent carbohydrate content at regular intervals',
   'probability': 0.6},
  {'action': 'Engaged in physical activity after dinner', 'probability': 0.3},
  {'action': 'Maintained a consistent sleep schedule and low stress levels',
   'probability': 0.1}]}
In [15]:
# Description

for sentence in response_json["qualitative_description"].split('. '):
    print(f"- {sentence.strip()}.")
- This individual leads a very structured and healthy lifestyle, which contributes to excellent glycemic control.
- They maintain a balanced diet with consistent carbohydrate intake at each meal, engage in moderate physical activity daily, such as a brisk walk after dinner, and prioritize getting 7-8 hours of quality sleep each night.
- Their stress levels are low, and they live in a temperate climate with consistent daylight hours throughout the year.
- As a result, their blood glucose levels are generally stable and predictable..
In [16]:
df = pd.DataFrame.from_records(response_json["sample_solutions"])

df.head()
Out[16]:
t c m a I_S I_E L g_0 g_1 g_2 G is_meal
0 0.000000 0.083045 0.853553 0.250723 0.152953 0.038349 0.000000e+00 0.1 0.1 0.1 0.3 False
1 1.043478 0.038009 0.935830 0.253929 0.083503 0.021204 3.000000e-08 0.1 0.1 0.1 0.3 False
2 2.086957 0.021421 0.985750 0.262773 0.038896 0.010221 1.144780e-05 0.1 0.1 0.1 0.3 False
3 3.130435 0.018138 0.997092 0.280742 0.028649 0.008043 8.732045e-04 0.1 0.1 0.1 0.3 False
4 4.173913 0.040626 0.924152 0.310228 0.094228 0.029232 1.822252e-02 0.1 0.1 0.1 0.3 False

Visualize (simple)¶

Glucose¶

In [17]:
df.plot(x="t", y="G")
Out[17]:
<Axes: xlabel='t'>
No description has been provided for this image

Endogenous currents¶

  • I_S : Insulin secretion (endogenous)
  • I_E : Effective Insulin (injected + endogenous)
  • L : ("Light") Photoperiod conveyed via hypothalamus
In [18]:
df.plot(x="t", y=["I_S", "I_E", "L", ])
Out[18]:
<Axes: xlabel='t'>
No description has been provided for this image

Visualize using pfun tools¶

In [19]:
from pfun_cma_model.engine.cma_plot import CMAPlotConfig
import matplotlib.pyplot as plt
plt.close('all')
cma_plot = CMAPlotConfig(plot_cols=["c", "m", "a"])
df['G_soln'] = df['G']  # just to satisfy the plot function
cma_plot().plot(df, plot_cols=["c", "m", "a"], separate2subplots=False)
Out[19]:
(<Figure size 1400x1000 with 2 Axes>,
 array([<Axes: >, <Axes: >], dtype=object))
No description has been provided for this image

Export notebook to HTML¶

./visualize-generated-scenarios.html

In [20]:
%%sh

uv run jupyter nbconvert --to html visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.html
cp visualize-generated-scenarios.html ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.html
[NbConvertApp] Converting notebook visualize-generated-scenarios.ipynb to html
[NbConvertApp] WARNING | Alternative text is missing on 3 image(s).
[NbConvertApp] Writing 467597 bytes to visualize-generated-scenarios.html
In [22]:
%%sh

uv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf
cp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf
[NbConvertApp] Converting notebook visualize-generated-scenarios.ipynb to pdf
[NbConvertApp] ERROR | Error while converting 'visualize-generated-scenarios.ipynb'
Traceback (most recent call last):
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/nbconvertapp.py", line 487, in export_single_notebook
    output, resources = self.exporter.from_filename(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 390, in from_filename
    return super().from_filename(filename, resources, **kw)  # type:ignore[return-value]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/exporter.py", line 201, in from_filename
    return self.from_file(f, resources=resources, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 396, in from_file
    return super().from_file(file_stream, resources, **kw)  # type:ignore[return-value]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/exporter.py", line 220, in from_file
    return self.from_notebook_node(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/pdf.py", line 184, in from_notebook_node
    latex, resources = super().from_notebook_node(nb, resources=resources, **kw)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/latex.py", line 92, in from_notebook_node
    return super().from_notebook_node(nb, resources, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 429, in from_notebook_node
    output = self.template.render(nb=nb_copy, resources=resources)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/jinja2/environment.py", line 1295, in render
    self.environment.handle_exception()
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/jinja2/environment.py", line 942, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/index.tex.j2", line 8, in top-level template code
    ((* extends cell_style *))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/style_jupyter.tex.j2", line 176, in top-level template code
    \prompt{(((prompt)))}{(((prompt_color)))}{(((execution_count)))}{(((extra_space)))}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/base.tex.j2", line 7, in top-level template code
    ((*- extends 'document_contents.tex.j2' -*))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/document_contents.tex.j2", line 51, in top-level template code
    ((*- block figure scoped -*))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/display_priority.j2", line 5, in top-level template code
    ((*- extends 'null.j2' -*))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 30, in top-level template code
    ((*- block body -*))
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/base.tex.j2", line 241, in block 'body'
    ((( super() )))
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 32, in block 'body'
    ((*- block any_cell scoped -*))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 85, in block 'any_cell'
    ((*- block markdowncell scoped-*)) ((*- endblock markdowncell -*))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/document_contents.tex.j2", line 68, in block 'markdowncell'
    ((( cell.source | citation2latex | strip_files_prefix | convert_pandoc('markdown+tex_math_double_backslash', 'json',extra_args=[]) | resolve_references | convert_explicitly_relative_paths | convert_pandoc('json','latex'))))
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/filters/pandoc.py", line 36, in convert_pandoc
    return pandoc(source, from_format, to_format, extra_args=extra_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 50, in pandoc
    check_pandoc_version()
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 98, in check_pandoc_version
    v = get_pandoc_version()
        ^^^^^^^^^^^^^^^^^^^^
  File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 75, in get_pandoc_version
    raise PandocMissing()
nbconvert.utils.pandoc.PandocMissing: Pandoc wasn't found.
Please check that pandoc is installed:
https://pandoc.org/installing.html
cp: cannot stat 'visualize-generated-scenarios.pdf': No such file or directory
---------------------------------------------------------------------------
CalledProcessError                        Traceback (most recent call last)
Cell In[22], line 1
----> 1 get_ipython().run_cell_magic('sh', '', '\nuv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf\ncp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf\n')

File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/interactiveshell.py:2565, in InteractiveShell.run_cell_magic(self, magic_name, line, cell)
   2563 with self.builtin_trap:
   2564     args = (magic_arg_s, cell)
-> 2565     result = fn(*args, **kwargs)
   2567 # The code below prevents the output from being displayed
   2568 # when using magics with decorator @output_can_be_silenced
   2569 # when the last Python token in the expression is a ';'.
   2570 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):

File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/magics/script.py:160, in ScriptMagics._make_script_magic.<locals>.named_script_magic(line, cell)
    158 else:
    159     line = script
--> 160 return self.shebang(line, cell)

File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/magics/script.py:348, in ScriptMagics.shebang(self, line, cell)
    343 if args.raise_error and p.returncode != 0:
    344     # If we get here and p.returncode is still None, we must have
    345     # killed it but not yet seen its return code. We don't wait for it,
    346     # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
    347     rc = p.returncode or -9
--> 348     raise CalledProcessError(rc, cell)

CalledProcessError: Command 'b'\nuv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf\ncp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf\n'' returned non-zero exit status 1.
In [ ]: