News 〉Releases

Helipad 1.0 Runs in Jupyter Notebooks, and Much More

Helipad 1.0 has just launched with a plethora of improvements. Most importantly: you can now run Helipad models in Jupyter notebooks.

Jupyter Integration

Jupyter notebooks are interactive documents into which you can embed Python code to run in-browser. They’re popular for sharing scientific code because putting code in a document can be much more readable than putting comments in code.

Helipad can now run a full-featured instance inside a Jupyter notebook, with the same control panel experience and interactive plotting. Anything you can do with the Tkinter frontend, you can now do in the Jupyter frontend as well, with no* changes to your code. (*except that you’ll need to launch the plots explicitly with a heli.launchVisual() line at the end)

To try out the new Jupyter frontend,

  1. Download one of the sample notebooks
  2. Install Jupyter and Ipywidgets using pip install jupyterlab and pip install ipywidgets
  3. Launch the notebook from your terminal using jupyter notebook /path/to/notebook.ipynb

Because the code can be written and run in-browser, this should flatten the learning curve for writing a Helipad model and increase the shareability of model code.

New Decorators

The most significant API update is a set of new decorators to add hooks and reporters. Previously, it was necessary to define a function and then register it using model.addHook(). This entailed a lot of repetition.

Starting with Helipad 1.0, you can now register hooks using a decorator syntax. Just name your function according to the hook, and add @heli.hook at the top.

from helipad import Helipad
heli = Helipad()

@heli.hook
def modelStep(model, stage):
    pass

You can also use @heli.hook('modelStep') if you want to hook a function of any name to the modelStep hook, for example.

There are also decorators for reporters and button shocks. Though most reporters will still be generated with the data methods, if you’re defining your own reporter function, you can register it with the @heli.reporter decorator. Similarly, you can add buttons easily to the control panel with @heli.button.

API Stability

With the release of Helipad 1.0, every effort will be made to maintain backward-compatibility. Documented functions and properties will not change before six months or two 0.1 releases after the first release in which they are deprecated, whichever is longer. Undocumented functions and properties can change without notice.

Other Improvements

  • Plotting is now completely independent of the control panel. So you can launch the traditional way with model.launchCpanel(), jump straight into plotting with model.launchVisual(), or go completely GUI-less with model.start() (In the latter two cases you’ll have to set parameter values, including any data post-processing, in code).
  • Param objects now allow you to enable and disable the GUI element.
  • Model control is handled in the model object now, rather than the Cpanel object. If you need to control the model with code, use model.start(), model.stop(), and model.terminate().
  • New parameter types checkentry and checkgrid can be registered with model.addParameter().
  • Sliders can be registered with discrete and arbitrary values by passing a list of values to the opts argument of model.addParameter().
  • The CSV and stop-after boxes, along with the refresh rate slider and the plot list, are now proper parameters and can be accessed and set using model.param() under the names 'csv', 'stopafter', 'updateEvery', and 'plots', respectively.
  • The stopafter parameter can be set to a function rather than a number, in order to stop the model after an arbitrary condition is fulfilled. This can also be used in parameter sweeps.
  • Plots can be activated and deactivated from code with the new Plot.active() method.

The full list of API changes is below.

API Changes in Version 1.0

  • ⚠️ HelipadRemoved model.defaultPlots. Select plots programmatically with the selected argument of model.addPlot(), or after the fact with TimeSeriesPlot.active().
    Moved Cpanel.graph and Cpanel.running to the model object.
    Model control (the start(), stop(), and terminate() methods) is handled here rather than in the Cpanel object.
    Removed the buttons property. The addButton() method now aliases Shocks.register().
  • ⚠️ addButtonPass the model object to the button function, and move the display from the top to the shocks section.
  • ⚠️ paramSweepRemoved the t parameter. Use model.param('stopafter') to set a time limit or a stop condition.
  • ⚠️ CpanelChanged name to Cpanel from GUI.
    Moved the graph and running properties to the model object, and the lastUpdate property to the Graph object.
    Removed the headless parameter and property. To run the model headless, run model.launchPlots() without running model.launchCpanel().
    The stopafter, updateEvery, csv, and checks properties, which formerly stored Tkinter widgets relating to configuration, have been removed. Their values can be accessed through parameters of the same name with model.param() except checks, which can now be accessed with model.param('plots').
    Moved model control methods run(), pause(), terminate(), and preparePlots() to model.start(), model.stop(), model.terminate(), and model.launchPlots(), respectively.
    With the plot list being a parameter now, the CpanelAbovePlotlist hook has been removed.
  • ⚠️ launchCpanelRenamed from model.launchGUI, and removed the headless parameter. To run the model headless, run model.launchPlots() without calling this function.
  • ⚠️ launchVisualMoved from Cpanel.preparePlots.
  • ⚠️ CpanelAboveItemParamsName changed from GUIAboveItemParams.
  • ⚠️ CpanelPreLaunchName changed from GUIPreLaunch.
  • ⚠️ CpanelPostInitName changed from GUIPostInit.
  • ⚠️ CpanelTopName changed from GUITop.
  • ⚠️ CpanelBottomName changed from GUIBottom.
  • ⚠️ CpanelAboveShocksName changed from GUIAboveShocks.
  • ⚠️ CpanelAboveParamsName changed from GUIAboveParams.
  • ⚠️ modelStopTakes the model object rather than the GUI object as the first argument.
  • ⚠️ terminateTakes the model object rather than the GUI object as the first argument.
  • ⚠️ GUICloseNever executes in a Jupyter environment.
  • launchCpanelInterrupts the 'Run All' sequence in a Jupyter environment.
  • @reporterIntroduced.
  • enableIntroduced.
  • disableIntroduced.
  • disabledIntroduced.
  • @buttonIntroduced.
  • @hookIntroduced.
  • genDecoratorIntroduced.
  • startIntroduced as part of the transfer of model control functions from GUI to the model object.
  • ParamAdded the defaultVal property, and split the parameter types into subclasses.
  • addAdded support for checkgrid, checkentry, and logslider parameters.
  • checkEntryAdded the command argument and callback parameters to enable callback functions.
  • disabledMade the second parameter optional to allow the entire checkGrid to be enabled or disabled at once.
  • addCheckNow returns the textCheck widget.
  • addAdded the prioritize argument.
  • TimeSeriesAdded the lastUpdate property, formerly from the GUI object.
  • logSliderWith the log slider now available for use in user-defined parameters, the Tkinter class now has a complement of methods: set, get, enable, disable, and disabled.
  • TimeSeriesPlotAdded the check and selected properties and the active() method.
  • activeIntroduced in the TimeSeriesPlot class.
  • visualLaunchIntroduced.