This tutorial provides a minimum working example (MWE) for an analysis scheme which may help you organize your code.
The calculator code (omnicalc) does two things: it runs calculations (one per simulation, saved to disk) and it plots results from many simulations. Typically plot scripts have a specific prefix i.e. calc/plot-protein_rmsd.py
and are automatically detected by the factory and listed on the calculator page for the factory graphical user interface (GUI). These plot scripts can be converted into interactive notebooks in GUI and then executed directly, saving plots to a special folder and presenting them in the notebook and on the calculator page. All plot scripts can also be run from the command line by running commands like make plot protein_rmsd
, as long as you have correctly prepared the metadata. This method always leaves the user in an interactive python session so they can inspect the data or develop more code. The user can run replot()
in this session to re-execute the code during development. This is the standard method for analyzing results.
There is also an alternate, autoplot method which adds a few features. Plot scripts which use this scheme can contain a decorated function which only runs once, even if the user runs replot()
many times to update their plots. This is useful when there is a lengthy loading process, in the case of very large calculation results, or if you would like to perform extensive post-post-processing (that’s not a typo — the calculations produce the “post-procesing” data). Every local variable in the loader function is exposed to globals so they do not need to be passed between functions.
An autoplot script can also contain specific decorated plot functions which can be plotted on the command line without an interactive terminal using commands like make plot undulations undulation_spectra
, where the undulation_spectra
function may be one of many plotting functions. This allows users to set default plot routines or call on specific plots which are not always run when the script is invoked. Since “plotting” is the only way that users can compare simulations, we have even relaxed the naming scheme so you can make a file called e.g. compare_structures.py
which compares all of your simulations and then run specific functions with e.g. make go compare_structures comparison_dev
.
To demonstrate the autoplot scheme, create a plot script called demonstrate_autoplot.py
with the following contents.
Then, add the following entry to your plots metadata. Ensure that you have a calculation called undulations
by adding this to an existing demonstration. We recommend piggybacking this on the end of the single pipeline walkthrough.
Navigate to the omnicalc directory, typically at factory/calc/project_name
. Note that make go
is equivalent to make plot
, to reflect the fact that “plot” scripts can be used for extensive analysis. We also set script: demonstrate_autoplot.py
otherwise the code assumes the default name, which would be plot-demo_autoplot.py
in this case. If you need to save data to disk, you should either use the store
function at omni.base.store
in your code or write a calculation, otherwise, you can use autoplot for extra analysis (this is why we allow make go
as well as make plot
).
Run make go demo_autoplot
. The output is given in a screenshot below.
The instructions explain how the code is executed, but in short, this script runs the load
function first, dumps all of its locals into globals, and then executes every function decorated with @autoplot(plotrun)
.
You can set plotrun.routine = ['plot2']
to ensure that a generic call to make go demo_autoplot
only runs that function, ignoring the plot
function. You can also set plotrun.routine = []
to run nothing, and use the standard if __name__=='__main__':
conditional to develop code in the global namespace. You can always manipulate plotrun.routine
on-the-fly. Lastly,
The script provided above includes all of the features in the autoplot scheme, reviewed below.
- A single function decorated with
@autoload(plotrun)
runs only once even if you repeatedly runreplot()
while developing your code. The load function runs before any global code if it is under aif __name__=='__main__':
block. All locals are exposed to the global namespace so you don’t have to pass them around. - Any functions decorated with
@autoplot(plotrun)
will run after loading. - These plot functions can be plotted without the interactive python session using
make go plot_name function_name
. - These functions are chosen by the
plotrun.routine
variable so that some non-standard plots can be ignored during normal execution and then selectively executed from the command line, or inside the interactive session.
You are welcome to set director: {'autoplot':True}
in your metadata to ensure that all plots use this scheme, otherwise you can set autoplot: True
in the metadata (see the example) above to use it on individual plots. The autoplot scheme was designed to eliminate conditionals and excessive control flow in existing plots developed by the authors. The use of decorators, the plotrun.routine
variable, and the control over the load function is useful when developing sprawling, modular analysis and plotting routines.