#!/usr/bin/env python
# coding: utf-8
# # T9 - Deployment
#
# This tutorial provides several useful recipes for deploying Covasim.
#
#
# Click [here](https://mybinder.org/v2/gh/institutefordiseasemodeling/covasim/HEAD?urlpath=lab%2Ftree%2Fdocs%2Ftutorials%2Ftut_deployment.ipynb) to open an interactive version of this notebook.
#
#
# ## Dask
#
# [Dask](https://dask.org/) is a powerful library for multiprocessing and "scalable" analytics. Using Dask (rather than the built-in `multiprocess`) for parallelization is _relatively_ straightforward:
# ```python
# import dask
# from dask.distributed import Client
# import numpy as np
# import covasim as cv
#
#
# def run_sim(index, beta):
# ''' Run a standard simulation '''
# sim = cv.Sim(beta=beta, label=f'Sim {index}, beta={beta}')
# sim.run()
# return sim
#
#
# if __name__ == '__main__':
#
# # Run settings
# n = 8
# n_workers = 4
# betas = np.sort(np.random.random(n))
#
# # Create and queue the Dask jobs
# client = Client(n_workers=n_workers)
# queued = []
# for i,beta in enumerate(betas):
# run = dask.delayed(run_sim)(i, beta)
# queued.append(run)
#
# # Run and process the simulations
# sims = list(dask.compute(*queued))
# msim = cv.MultiSim(sims)
# msim.plot(color_by_sim=True)
# ```
# ## Jupyter/IPython
#
# Using Jupyter and [VoilĂ ](https://voila.readthedocs.io/), you can build a Covasim-based webapp in minutes. First, install the required dependencies:
#
# ```bash
# pip install jupyter jupyterlab jupyterhub ipympl voila
# ```
#
# Here is a very simple interactive webapp that runs a multisim (in parallel!) when the button is pressed, and displays the results:
# ```python
# import numpy as np
# import covasim as cv
# import ipywidgets as widgets
#
# # Create the button and output area
# button = widgets.Button(description='Run')
# output = widgets.Output()
#
# @output.capture()
# def run():
# ''' Stochastically run a parallelized multisim '''
# sim = cv.Sim(verbose=0, pop_size=20e3, n_days=100, rand_seed=np.random.randint(99))
# msim = cv.MultiSim(sim)
# msim.run(n_runs=4)
# return msim.plot()
#
# def click(b):
# ''' Rerun on click '''
# output.clear_output(wait=True)
# run()
#
# # Create and show the app
# button.on_click(click)
# app = widgets.VBox([button, output])
# display(app)
# ```
# If you save this as e.g. `msim.ipynb`, then you can turn it into a web server simply by typing `voila msim.ipynb`.