Пример #1
0
	def __init__(self,fn,previous=False,autoreload=False):

		"""
		Note that we initialize paths.yaml and superficial data first, then load from the workspace or
		parse the dataset if the workspace was not saved.
		"""
		self.filename = path_expand(fn)
		self.paths = unpacker(conf_paths)
		self.machine = unpacker(conf_gromacs,'machine_configuration')[machine_name]
		del sys.modules['yaml']

		self.nprocs = self.machine['nprocs'] if 'nprocs' in self.machine else 1
		#---write timeseries to the post data directory when making slices
		self.write_timeseries_to_disk = self.paths.get('timekeeper',False)
		self.postdir = os.path.join(path_expand(self.paths['post_data_spot']),'')
		self.plotdir = os.path.join(path_expand(self.paths['post_plot_spot']),'')
		#---generic variables associated with the workspace
		self.vars = {}
		self.meta = {}
		self.calc = {}
		#---automatically add preexisting files to the workspace if they are found
		self.autoreload = autoreload

		#---for each "spot" in the yaml file, we construct a template for the data therein
		#---the table of contents ("toc") holds one parsing for every part regex in every spot
		self.spots,self.toc = {},collections.OrderedDict()
		for name,details in self.paths['spots'].items():
			rootdir = os.path.join(details['route_to_data'],details['spot_directory'])
			if not os.path.isdir(rootdir):
				raise Exception('\n[ERROR] cannot find root directory %s'%rootdir)
			for part_name,part_regex in details['regexes']['part'].items():
				spot = (name,part_name)
				self.toc[spot] = {}
				self.spots[spot] = {
					'rootdir':os.path.join(rootdir,''),
					'top':details['regexes']['top'],
					'step':details['regexes']['step'],
					'part':part_regex,
					'namer':eval(details['namer']),
					'namer_text':details['namer'],
					}
				self.spots[spot]['divy_keys'] = self.divy_keys(spot)
		#---we always require an xtc entry in the parts list
		if 'xtc' not in zip(*self.spots.keys())[1]: 
			raise Exception('\n[ERROR] you must have "xtc" in the parts list')
		#---set a cursor which specifies the active spot which should always be the first in the yaml
		self.cursor = self.spots.keys()[0]
		#---the self.c variable holds the top spot name but not the part name
		self.c = self.cursor[0]
		#---! default to XTC
		self.trajectory_format = 'xtc'
		self.merge_method = self.paths.get('merge_method','careful')
		
		#---open self if the filename exists 
		#---note that we save parser results but not details from paths.yaml in case these change
		if os.path.isfile(self.filename): 
			self.load(previous=previous)
			self.verify()
		#---otherwise make a new workspace
		else: self.bootstrap()
Пример #2
0
def plot(plotname=None,nox=False,workspace=None,specfile=None,plotlog=False,**kwargs):

	"""
	Run a plotting routine.
	"""

	from copy import deepcopy
	if plotname == None:
		from base.workspace import Workspace
		if workspace == None: workspace = unpacker(conf_paths)['workspace_spot']
		work = Workspace(workspace,previous=False)
		specs = work.load_specs()
		plotnames = specs['plots'].keys()
	else: plotnames = [plotname]
	#---for each desired plot type
	for pname in plotnames:
		fns = []
		for (dirpath, dirnames, filenames) in os.walk('./'): 
			fns.extend([dirpath+'/'+fn for fn in filenames])
		search = filter(lambda x:re.match('^\.\/[^omni].+\/plot-%s\.py$'%pname,x),fns)
		if len(search)!=1: status('unclear search for %s: %s'%(pname,str(search)))
		else: 
			if plotname==None: 
				cmd = 'python '+search[0]+' nox quit=True '+' "%s"'%str(kwargs)+\
					(' &> %s'%plotlog if plotlog else '')
			else: 
				status('rerun the plot with:\n\nexecfile(\''+search[0]+'\')\n',tag='note')
				cmd = "python -i "+search[0]+(' nox' if nox else '')+' "%s"'%str(kwargs)
				#---! add log here? is the user or factory ever going to use this?
			status('calling: "%s"'%cmd,tag='status')
			os.system(cmd)
Пример #3
0
def export_to_factory(project_name,project_location,workspace=None):

	"""
	Export the simulation data from the toc to the factory database.
	Users should not run this.
	"""

	sys.path.insert(0,project_location)
	os.environ.setdefault("DJANGO_SETTINGS_MODULE",project_name+".settings")
	import django
	#---! a fairly extreme hack. this function needs a lot of work. the paths are almost certainly fubar
	sys.path.insert(0,os.path.join(os.path.abspath(os.path.join(project_location,'../../')),'dev'))
	django.setup()
	from simulator import models
	from base.workspace import Workspace
	workspace = unpacker(conf_paths)['workspace_spot']
	work = Workspace(workspace)
	sns={}
	for key in work.toc.keys():
		for sn in work.toc[key]:
			sns[sn]=key[0]
	for sn in sns.keys():
		if any([sn in work.toc[i] for i in work.toc.keys() if i[1]=='edr']) and (
			any([sn in work.toc[i] for i in work.toc.keys() if i[1]=='trr']) or
			any([sn in work.toc[i] for i in work.toc.keys() if i[1]=='xtc'])):
			spot=(sns[sn],'edr')
			name=work.prefixer(sn)
			try: models.Simulation(name=name,program="protein",code=sn).save()
			except: print '[NOTE] simulation "%s" already exists in the database'%name
	if not sns: print "[STATUS] nothing to export"
Пример #4
0
def refresh(autoreload=True):

	"""
	If you have new data or more data (i.e. more XTC files or longer trajectories) you must
	run refresh in order to add those files to the tables of contents.
	"""

	from base.workspace import Workspace
	workspace = unpacker(conf_paths)['workspace_spot']
	work = Workspace(workspace,autoreload=autoreload)
	work.bootstrap()
	work.save()
Пример #5
0
def compute(calculation_name=None,autoreload=True):

	"""
	Open the workspace, parse a YAML script with instructions, save, and exit.
	Note that we may specify a particular calculation if there are many pending calculations.
	"""

	from base.workspace import Workspace
	workspace = unpacker(conf_paths)['workspace_spot']
	work = Workspace(workspace,autoreload=autoreload)
	work.action(calculation_name=calculation_name)
	work.save()
Пример #6
0
	def action(self,calculation_name=None):
	
		"""
		Parse a specifications file to make changes to a workspace.
		This function interprets the specifications and acts on it. 
		It manages the irreducible units of an omnicalc operation and ensures
		that the correct data are sent to analysis functions in the right order.
		"""

		status('parsing specs file',tag='status')

		#---load the yaml specifications file
		specs = self.load_specs()
		#### status('done loading specs',tag='status')		
		
		#---read simulations from the slices dictionary
		sns = specs['slices'].keys()
		#---variables are passed directly to self.vars
		self.vars = deepcopy(specs['variables']) if 'variables' in specs else {}

		#---apply "+"-delimited internal references in the yaml file
		for path,sub in [(i,j[-1]) for i,j in catalog(specs) if type(j)==list 
			and type(j)==str and re.match('^\+',j[-1])]:
			source = delve(self.vars,*sub.strip('+').split('/'))
			point = delve(specs,*path[:-1])
			point[path[-1]][point[path[-1]].index(sub)] = source
		for path,sub in [(i,j) for i,j in catalog(specs) if type(j)==str and re.match('^\+',j)]:
			source = delve(self.vars,*sub.strip('+').split('/'))
			point = delve(specs,*path[:-1])
			point[path[-1]] = source
		
		#---loop over all simulations to create groups and slices
		self.save(quiet=True)
		for route in [('slices',i) for i in sns]:
			root,sn = delve(specs,*route),route[-1]
			#---create groups
			if 'groups' in root:
				for group,select in root['groups'].items():
					kwargs = {'group':group,'select':select,'sn':sn}
					self.create_group(**kwargs)
				root.pop('groups')
			#---slice the trajectory
			if 'slices' in root:
				for sl,details in root['slices'].items(): 
					#---! use a default group here?
					for group in details['groups']:
						kwargs = {'sn':sn,'start':details['start'],
							'end':details['end'],'skip':details['skip'],'slice_name':sl}
						kwargs['group'] = group
						if 'pbc' in details: kwargs['pbc'] = details['pbc']
						self.create_slice(**kwargs)
				root.pop('slices')
			if root != {}: raise Exception('[ERROR] unprocessed specifications %s'%str(root))
			else: del root
		#---we only save after writing all slices. if the slicer fails autoreload will find preexisting files
		self.save(quiet=True)
		checktime()

		#---meta is passed to self.meta
		if 'meta' in specs:
			for sn in specs['meta']:
				self.meta[sn] = specs['meta'][sn]

		#---collections are groups of simulations
		if 'collections' in specs: self.vars['collections'] = specs['collections']

		#---calculations are executed last and organized in this loop
		if 'calculations' in specs:
			status('starting calculations',tag='status')
			#---note that most variables including calc mirror the specs file
			self.calc = dict(specs['calculations'])
			#---infer the correct order for the calculation keys from their upstream dependencies
			upstream_catalog = [i for i,j in catalog(self.calc) if 'upstream' in i]
			#---if there are no specs required to get the upstream data object the user can either 
			#---...use none/None as a placeholder or use the name as the key as in "upstream: name"
			for uu,uc in enumerate(upstream_catalog):
				if uc[-1]=='upstream': upstream_catalog[uu] = upstream_catalog[uu]+[delve(self.calc,*uc)]
			depends = {t[0]:[t[ii+1] for ii,i in enumerate(t) if ii<len(t)-1 and t[ii]=='upstream'] 
				for t in upstream_catalog}
			calckeys = [i for i in self.calc if i not in depends]
			#---check that the calckeys has enough elements 
			list(set(calckeys+[i for j in depends.values() for i in j]))			
			#---! come back to this!
			while any(depends):
				ii,i = depends.popitem()
				if all([j in calckeys for j in i]) and i!=[]: calckeys.append(ii)
				else: depends[ii] = i
			#---if a specific calculation name is given then only perform that calculation
			if not calculation_name is None: calckeys = [calculation_name]
			for calcname in calckeys:
				details = specs['calculations'][calcname]
				status('checking calculation %s'%calcname,tag='status')
				new_calcs = self.interpret_specs(details)
				#---perform calculations
				for calc in new_calcs:
					#---find the script with the funtion
					fns = []
					for (dirpath, dirnames, filenames) in os.walk('./'): 
						fns.extend([dirpath+'/'+fn for fn in filenames])
					search = filter(lambda x:re.match('^\.\/[^ate].+\/%s\.py$'%calcname,x),fns)
					if len(search)==0: raise Exception('\n[ERROR] cannot find %s.py'%calcname)
					elif len(search)>1: raise Exception('\n[ERROR] redundant matches: %s'%str(search))
					else:
						sys.path.insert(0,os.path.dirname(search[0]))
						function = unpacker(search[0],calcname)
						status('computing %s'%calcname,tag='loop')
						computer(function,calc=calc,workspace=self)
						self.save()
					checktime()
		self.save()
Пример #7
0
    import matplotlib

    matplotlib.use("Agg")
if building_docs:
    sys.path.insert(0, "../../../omni")
from base.workspace import Workspace
from base.tools import status, unpacker, flatten, unique
from base.store import picturedat, picturefind, datmerge
from base.timer import checktime
from functools import wraps

conf_paths, conf_gromacs = "paths.yaml", "gromacs.py"

# ---get the active workspace
if "work" not in globals() and not building_docs:
    workspace = unpacker(conf_paths)["workspace_spot"]
    work = Workspace(workspace, previous=False)

# ---INTERFACE


def workspace(func):

    """
	This decorator tacks on the workspace to the function.
	"""

    @wraps(func)
    def mod(*args, **kwargs):
        kwargs["workspace"] = work
        return func(*args, **kwargs)