# Execution Plans¶

You are free to conduct your simulations from a notebook but normally you will use a script. The main point about adaptivity is to make decision about tasks along the way.

We want to first look into a way to run python code asynchroneously in the project. For this, we write a function that should be executed. Inside you will create tasks and submit them.

If the function should pause, use yield as if you would return and exit the function. Yield will allow you to continue at this

yield {condition_to_continue}


This will interrupt your script until the function you return will return True when called. An example

def strategy(loops=10, trajs_per_loop=4, length=100):
for loop in range(loops):
trajectories = project.new_ml_trajectory(length, trajs_per_loop)

# continue if ALL of the tasks are done (can be failed)

# submit a model job

# when it is done do next loop


and add the event to the project (these cannot be stored yet!)

project.add_event(strategy(loops=2))

<adaptivemd.event.FunctionalEvent at 0x10d615050>


What is missing now? The adding of the event triggered the first part of the code. But to recheck if we should continue needs to be done manually.

RP has threads in the background and these can call the trigger whenever something changed or finished.

Still that is no problem, we can do that easily and watch what is happening

Let’s see how our project is growing. TODO: Add threading.Timer to auto trigger.

import time
from IPython.display import clear_output

try:
while project._events:
clear_output(wait=True)
print '# of files  %8d : %s' % (len(project.trajectories), '#' * len(project.trajectories))
print '# of models %8d : %s' % (len(project.models), '#' * len(project.models))
sys.stdout.flush()
time.sleep(2)
project.trigger()

except KeyboardInterrupt:
pass

# of files        74 : ##########################################################################
# of models       33 : #################################


Let’s do another round with more loops

project.add_event(strategy(loops=2))

<adaptivemd.event.FunctionalEvent at 0x10d633850>


And some analysis (might have better functions for that)

# find, which frames from which trajectories have been chosen
trajs = project.trajectories
q = {}
ins = {}
for f in trajs:
source = f.frame if isinstance(f.frame, File) else f.frame.trajectory
ind = 0 if isinstance(f.frame, File) else f.frame.index
ins[source] = ins.get(source, []) + [ind]

for a,b in ins.iteritems():
print a.short, ':', b

file://{}/alanine.pdb : [0, 0, 0]
sandbox:///{}/00000005/ : [95, 92, 67, 92]
sandbox:///{}/00000007/ : [11]
sandbox:///{}/00000011/ : [55]
sandbox:///{}/00000000/ : [28, 89, 72]
sandbox:///{}/00000002/ : [106]
sandbox:///{}/00000004/ : [31, 25, 60]


## Event¶

And do this with multiple events in parallel.

def strategy2():
for loop in range(10):
num = len(project.trajectories)
# continue only when there are at least 2 more trajectories
yield project.on_ntraj(num + 2)

project.add_event(strategy(loops=10, trajs_per_loop=2))

<adaptivemd.event.FunctionalEvent at 0x107744c90>

project.wait_until(project.events_done)

 ExecutionPlan(generator) An wrap to turn python function into asynchronous execution