In [1]:
import sys, os, time
We want to stop RP from reporting all sorts of stuff for this example so we set a specific environment variable to tell RP to do so. If you want to see what RP reports change it to REPORT
.
In [2]:
# verbose = os.environ.get('RADICAL_PILOT_VERBOSE', 'REPORT')
os.environ['RADICAL_PILOT_VERBOSE'] = 'ERROR'
We will import the appropriate parts from AdaptiveMD as we go along so it is clear what it needed at what stage. Usually you will have the block of imports at the beginning of your script or notebook as suggested in PEP8.
In [3]:
from adaptivemd import Project
In [4]:
from adaptivemd.engine.openmm import OpenMMEngine
from adaptivemd.analysis.pyemma import PyEMMAAnalysis
from adaptivemd import File, Directory, WorkerScheduler
Let's open a project with a UNIQUE name. This will be the name used in the DB so make sure it is new and not too short. Opening a project will always create a non-existing project and reopen an exising one. You cannot chose between opening types as you would with a file. This is a precaution to not accidentally delete your project.
In [5]:
# Project.delete('test')
In [6]:
project = Project('testcase-worker')
Now we have a handle for our project. First thing is to set it up to work on a resource.
In [98]:
print len([t for t in project.trajectories if t.exists])
In [99]:
for w in project.workers:
print w.hostname, w.state
In [14]:
from uuid import UUID
In [15]:
import datetime
datetime.datetime.fromtimestamp(modeller.__time__).strftime("%Y-%m-%d %H:%M:%S")
Out[15]:
In [16]:
project.generators.add(engine)
project.generators.add(modeller)
In [17]:
sc = WorkerScheduler(project.resource)
sc.enter(project)
In [18]:
t = engine.task_run_trajectory(project.new_trajectory(pdb_file, 100, restart=True)). extend(50).extend(100)
In [54]:
sc(t)
Out[54]:
In [63]:
sc.advance()
In [ ]:
In [64]:
print project.generators
In [17]:
t1 = engine.task_run_trajectory(project.new_trajectory(pdb_file, 100, restart=True))
t2 = t1.extend(100)
In [18]:
t2.trajectory.restart
Out[18]:
In [19]:
project.tasks.add(t2)
In [24]:
for f in project.trajectories:
print f.drive, f.basename, len(f), f.created, f.__time__, f.exists, hex(f.__uuid__)
In [27]:
for f in project.files:
print f.drive, f.path, f.created, f.__time__, f.exists, hex(f.__uuid__)
In [22]:
w = project.workers.last
print w.state
print w.command
In [23]:
for t in project.tasks:
print t.state, t.worker.hostname if t.worker else 'None'
In [17]:
In [18]:
In [19]:
In [20]:
Out[20]:
In [24]:
sc.advance()
In [33]:
t1 = engine.task_run_trajectory(project.new_trajectory(pdb_file, 100))
t2 = t1.extend(100)
In [34]:
project.tasks.add(t2)
In [35]:
# from adaptivemd.engine import Trajectory
# t3 = engine.task_run_trajectory(Trajectory('staging:///trajs/0.dcd', pdb_file, 100)).extend(100)
# t3.dependencies = []
# def get_created_files(t, s):
# if t.is_done():
# print 'done', s
# return s - set(t.added_files)
# else:
# adds = set(t.added_files)
# rems = set(s.required[0] for s in t._pre_stage)
# print '+', adds
# print '-', rems
# q = set(s) - adds | rems
# if t.dependencies is not None:
# for d in t.dependencies:
# q = get_created_files(d, q)
# return q
# get_created_files(t3, {})
In [42]:
for w in project.workers:
print w.hostname, w.state
In [43]:
w = project.workers.last
print w.state
print w.command
In [39]:
w.command = 'shutdown'
In [38]:
for t in project.tasks:
print t.state, t.worker.hostname if t.worker else 'None'
In [112]:
for f in project.trajectories:
print f.drive, f.basename, len(f), f.created, f.__time__, f.exists, hex(f.__uuid__)
In [138]:
project.trajectories.one[0]
Out[138]:
In [139]:
t = engine.task_run_trajectory(project.new_trajectory(project.trajectories.one[0], 100))
In [140]:
project.tasks.add(t)
In [141]:
print project.files
print project.tasks
In [30]:
t = modeller.execute(list(project.trajectories))
In [32]:
project.tasks.add(t)
In [34]:
from uuid import UUID
In [ ]:
project.storage.tasks._document.find_one({'_dict': {'generator' : { '_dict': }}})
In [56]:
genlist = ['openmm']
Out[56]:
In [51]:
scheduler = sc
prefetch = 1
while True:
scheduler.advance()
if scheduler.is_idle:
for _ in range(prefetch):
tasklist = scheduler(project.storage.tasks.consume_one())
if len(tasklist) == 0:
break
time.sleep(2.0)
Note, that you cannot add the same engine twice. But if you create a new engine it will be considered different and hence you can store it again.
Finally we are ready to run a first trajectory that we will store as a point of reference in the project. Also it is nice to see how it works in general.
the .get_scheduler
function delegates to the resource and uses the get_scheduler
functions from there. This is merely a convenience since a Scheduler
has the responsibility to open queues on the resource for you.
You have the same options as the queue has in the resource. This is often the number of cores and walltime, but can be additional ones, too.
Let's open the default queue and use a single core for it since we only want to run one simulation.
In [15]:
scheduler = project.get_scheduler(cores=1)
Next we create the parameter for the engine to run the simulation. Since it seemed appropriate we use a Trajectory
object (a special File
with initial frame and length) as the input. You could of course pass these things separately, but this way, we can actualy reference the no yet existing trajectory and do stuff with it.
A Trajectory should have a unique name and so there is a project function to get you one. It uses numbers and makes sure that this number has not been used yet in the project.
In [16]:
trajectory = project.new_trajectory(engine['pdb_file'], 100)
trajectory
Out[16]:
This says, initial is alanine.pdb
run for 100 frames and is named xxxxxxxx.dcd
.
Now, we want that this trajectory actually exists so we have to make it (on the cluster which is waiting for things to do). So we need a Task
object to run a simulation. Since Task
objects are very flexible there are helper functions to get them to do, what you want, like the ones we already created just before. Let's use the openmm engine to create an openmm task
In [17]:
task = engine.task_run_trajectory(trajectory)
That's it, just that a trajectory description and turn it into a task that contains the shell commands and needed files, etc.
Last step is to really run the task. You can just use a scheduler as a function or call the .submit()
method.
In [18]:
scheduler(task)
Out[18]:
Now we have to wait. To see, if we are done, you can check the scheduler if it is still running tasks.
In [26]:
scheduler.is_idle
Out[26]:
In [35]:
print scheduler.generators
or you wait until it becomes idle using .wait()
In [27]:
# scheduler.wait()
If all went as expected we will now have our first trajectory.
In [28]:
print project.files
print project.trajectories
Excellent, so cleanup and close our queue
In [67]:
scheduler.exit()
and close the project.
In [68]:
project.close()
The final project.close() will also shut down all open schedulers for you, so the exit command would not be necessary here. It is relevant if you want to exit the queue as soon as possible to save walltime.
You have finally created an AdaptiveMD project and run your first trajectory. Since the project exists now, it is much easier to run more trajectories now.
In [ ]: