def install_notebook_widgets(origin_base, dest_base, verbose=False): ''' Convenience wrapper around :py:func:`~notebook.install_nbextension` that installs Jupyter notebook extensions using a systematic naming convention ( mimics the source directory and file name structure rather than installing as a flat file set). This function will read the special file "__paths__" to collect dependencies not present in the nbextensions directory. Args: origin_base (str): Location of extension source code dest_base (str): Destination location (system and/or user specific) verbose (bool): Verbose installation (default False) See Also: The configuration module :mod:`~exa._config` describes the default arguments used by :func:`~exa._install.install` during installation. ''' try: shutil.rmtree(dest_base) except: pass for root, subdirs, files in os.walk(origin_base): for filename in files: subdir = root.split('nbextensions')[-1] orig = mkp(root, filename) dest = mkp(dest_base, subdir, mk=True) install_nbextension(orig, verbose=verbose, overwrite=True, nbextensions_dir=dest)
def install(persist=False, verbose=False): ''' Initializes exa's database and notebook widget features. By default, exa runs in memory. To take full advantage of exa's content management features this function should be run. It will create a storage location in **~/.exa** where all configuration, log, and data are housed. Args: exa_root (str): If None assumes temporary session, otherwise directory path where the package will be installed ''' if persist: rel_cleanup() config_cleanup() if platform.system().lower() == 'windows': dot_exa = mkp(os.getenv('USERPROFILE'), '.exa') else: dot_exa = mkp(os.getenv('HOME'), '.exa') mkp(dot_exa, mk=True) update_config() save_config() init_db() global engine from exa.relational.base import engine setup_loggers() update(verbose)
def create_atom(path, prefix, symbols): """ Create a :class:`~atomic.atom.Atom`. """ df1 = parse_pos(mkp(path, prefix + '.pos'), include_frame=True) df2 = parse_vel(mkp(path, prefix + '.vel'), include_frame=False) n = len(df1) // len(symbols) df1['symbol'] = pd.Series(symbols * n, dtype='category') df1['vx'] = df2['vx'] df1['vy'] = df2['vy'] df1['vz'] = df2['vz'] df1.dropna(axis=0, how='any', inplace=True) return Atom(df1)
def write(self, path, trajectory=True, float_format='% .8f'): ''' Write an xyz file (or files) to disk. Args: path (str): Directory or file path trajectory (bool): Write xyz trajectory file (default) or individual Returns: path (str): On success, return the directory or file path written ''' if trajectory: with open(path, 'w') as f: f.write(str(self)) else: grps = self.atom.groupby('frame') n = len(str(self['frame'].values.max())) for frame, atom in grps: filename = str(frame).zfill(n) + '.xyz' with open(mkp(path, filename), 'w') as f: a = atom[self._cols].copy() a['x'] *= Length['au', 'A'] a['y'] *= Length['au', 'A'] a['z'] *= Length['au', 'A'] a.to_csv(f, header=False, index=False, sep=' ', float_format=float_format, quoting=csv.QUOTE_NONE, escapechar=' ')
def load_constant_data(): """Load constants into the database (replacing existing).""" path = mkp(config['dynamic']['pkgdir'], '_static', 'constants.json') df = pd.read_json(path) df.reset_index(inplace=True) df.columns = ['symbol', 'value'] df['pkid'] = df.index df.to_sql(name='constant', con=engine, index=False, if_exists='replace')
def setUp(self): """ Generate the file path to the exa.editor module (which will be used as the test for the :class:`~exa.editor.Editor` class that it provides). """ self.path = mkp(config['dynamic']['pkgdir'], 'editor.py') with open(self.path) as f: self.lines = f.readlines() self.fl = Editor.from_file(self.path)
def load_isotope_data(): """Load isotope data into the database (replacing existing).""" path = mkp(config['dynamic']['pkgdir'], '_static', 'isotopes.json') df = pd.read_json(path, orient='values') df.columns = ('A', 'Z', 'af', 'eaf', 'color', 'radius', 'gfactor', 'mass', 'emass', 'name', 'eneg', 'quadmom', 'spin', 'symbol', 'szuid', 'strid') df.index.names = ['pkid'] df.reset_index(inplace=True) df.to_sql(name='isotope', con=engine, index=False, if_exists='replace')
def get_save_dirs(path): """ Find the save directories in a given path. Args: path (str): Output directory path Returns: dirs (list): List of save directories """ return [p for p in os.listdir(path) if os.path.isdir(mkp(path, p)) and 'save' in p]
def install_notebook_widgets(pkg_nbext, sys_nbext, verbose=False): ''' Convenience wrapper around :py:func:`~notebook.install_nbextension` that organizes notebook extensions for exa and related packages in a systematic fashion. Args: pkg_nbext (str): Path to the "_nbextension" directory in the source sys_nbext (str): Path to the system "nbextensions" directory verbose (bool): Verbose installation ''' try: shutil.rmtree(sys_nbext) except FileNotFoundError: pass for root, subdirs, files in os.walk(pkg_nbext): for filename in files: subdir = root.split('_nbextension')[-1] orig = mkp(root, filename) dest = mkp(sys_nbext, subdir, mk=True) install_nbextension(orig, verbose=verbose, overwrite=True, nbextensions_dir=dest)
def create_frame(path, prefix, nat, evp_cols=evp_cols, nos_cols=nos_cols): """ Create a :class:`~atomic.frame.Frame` from dynamics data. Args: path (str): Directory path prefix (str): Output file prefix nat (int): Number of atoms per frame evp_cols (list): Header for the evp file nos_cols (list): Header for the nos file """ df = parse_evp(mkp(path, prefix + '.evp')) df1 = parse_cel(mkp(path, prefix + '.cel')) for col in df1.columns: df[col] = df1[col] df1 = parse_nos(mkp(path, prefix + '.nos')) for col in df1.columns: df[col] = df1[col] df['atom_count'] = nat df['periodic'] = True df.dropna(axis=0, how='any', inplace=True) return Frame(df)
def parse_datafile(save_dir): """ Parses the standand data-file.xml output file from cp.x calculations. Args: save_dir (str): Save directory path Returns: d (dict): Dictionary of parsed data key, value pairs """ od = None with open(mkp(save_dir, 'data-file.xml'), 'rb') as f: od = xmltodict.parse(f) symbols = [od['Root']['IONS'][sym]['@SPECIES'].strip() for sym in od['Root']['IONS'].keys() if 'ATOM.' in sym ] ntype = int(od['Root']['IONS']['NUMBER_OF_SPECIES']['#text']) order = {} for i, j in enumerate(range(1, ntype + 1)): order[od['Root']['IONS']['SPECIE.' + str(j)]['ATOM_TYPE']['#text']] = i symbols = [(sym, order[sym]) for sym in symbols] symbols = [sym[0] for sym in sorted(symbols, key=itemgetter(1))] return {'symbols': symbols, 'order': order};
def load_unit_data(): """ Load unit conversions into the database (replacing existing). Note: This function actually computes (prior to bulk inserting data) conversion factors. """ path = mkp(config['dynamic']['pkgdir'], '_static', 'units.json') df = pd.read_json(path) for column in df.columns: series = df[column].dropna() values = series.values labels = series.index n = len(values) factor = (values.reshape(1, n) / values.reshape(n, 1)).ravel() from_unit, to_unit = zip(*product(labels, labels)) df_to_save = pd.DataFrame.from_dict({'from_unit': from_unit, 'to_unit': to_unit, 'factor': factor}) df_to_save['pkid'] = df_to_save.index df_to_save.to_sql(name=column, con=engine, index=False, if_exists='replace')
def parse_dynamics_dir(path): """ Parse a molecular dynamics simulation given the "outdir". Args: path (str): Location of QE's output directory ("outdir") Returns: universe (:class:`~atomic.universe.Universe`): An atomic universe """ save_dirs = get_save_dirs(path) if len(save_dirs) == 0: raise CPException('No .save directory in path {}.'.format(path)) prefix = save_dirs[0].split('_')[0] data = parse_datafile(mkp(path, save_dirs[0])) symbols = data['symbols'] nat = len(symbols) atom = create_atom(path, prefix, symbols) frame = create_frame(path, prefix, nat) meta = {'path': path, 'prefix': prefix, 'program': 'qe'} return Universe(name=prefix, description=path, atom=atom, frame=frame, meta=meta)
This module adds dynamic (only) configuration parameters. For complete configuration options and usage see `exa`_. .. _exa: https://github.com/exa-analytics/exa """ import os import shutil import atexit from exa.utility import mkp from exa._config import config def set_update(): config['exatomic']['update'] = '1' def del_update(): config['exatomic']['update'] = '0' config['dynamic']['exatomic_pkgdir'] = os.path.dirname(__file__) if 'exatomic' not in config: config['exatomic'] = {'update': '1'} if config['exatomic']['update'] == '1': shutil.copyfile(mkp(config['dynamic']['exatomic_pkgdir'], '_static', 'exatomic_demo.ipynb'), mkp(config['dynamic']['exa_root'], 'notebooks', 'exatomic_demo.ipynb')) shutil.copyfile(mkp(config['dynamic']['exatomic_pkgdir'], '_static', 'porphyrin.xyz'), mkp(config['dynamic']['exa_root'], 'data', 'examples', 'porphyrin.xyz')) atexit.register(del_update)
def install_notebook_widgets(pkg_nbext, sys_nbext, verbose=False): ''' Convenience wrapper around :py:func:`~notebook.install_nbextension` that organizes notebook extensions for exa and related packages in a systematic fashion. Args: pkg_nbext (str): Path to the "_nbextension" directory in the source sys_nbext (str): Path to the system "nbextensions" directory verbose (bool): Verbose installation ''' try: shutil.rmtree(sys_nbext) except FileNotFoundError: pass for root, subdirs, files in os.walk(pkg_nbext): for filename in files: subdir = root.split('_nbextension')[-1] orig = mkp(root, filename) dest = mkp(sys_nbext, subdir, mk=True) install_nbextension(orig, verbose=verbose, overwrite=True, nbextensions_dir=dest) if config['js']['update'] == '1': verbose = True if config['log']['level'] != '0' else False pkg_nbext = mkp(config['dynamic']['pkgdir'], '_nbextension') sys_nbext = mkp(jupyter_data_dir(), 'nbextensions', 'exa') install_notebook_widgets(pkg_nbext, sys_nbext, verbose) atexit.register(del_update)
def update_config(): ''' Populates the exa's configuration dictionary, **config** (typically aliased as **global_config**). ''' global config dot_exa = None config['exa_persistent'] = False if platform.system().lower() == 'windows': dot_exa = mkp(os.getenv('USERPROFILE'), '.exa') else: dot_exa = mkp(os.getenv('HOME'), '.exa') if os.path.exists(dot_exa): config['exa_root'] = dot_exa config['exa_persistent'] = True else: config['exa_root'] = mkdtemp() config['runlevel'] = 0 config['log_db'] = mkp(config['exa_root'], 'db.log') config['log_sys'] = mkp(config['exa_root'], 'sys.log') config['log_user'] = mkp(config['exa_root'], 'user.log') config['logfile_max_bytes'] = 1048576 config['logfile_max_count'] = 5 pkg = os.path.dirname(__file__) config['app_templates'] = mkp(pkg, '_app', 'templates') config['app_html'] = mkp(pkg, '_app', 'html') config['app_css'] = mkp(pkg, '_app', 'css') config['app_js'] = mkp(pkg, '_app', 'js') config['static_constants.json'] = mkp(pkg, '_static', 'constants.json') config['static_isotopes.json'] = mkp(pkg, '_static', 'isotopes.json') config['static_units.json'] = mkp(pkg, '_static', 'units.json') config['nbext_localdir'] = mkp(pkg, '_nbextensions') config['nbext_sysdir'] = mkp(jupyter_data_dir(), '_nbextensions', 'exa') config['notebook'] = False try: cfg = get_ipython().config if 'IPKernelApp' in cfg: config['notebook'] = True except: pass config['pkg_numba'] = False config['pkg_dask'] = False config['pkg_distributed'] = False try: import numba config['pkg_numba'] = True except: pass try: import dask config['pkg_dask'] = True except: pass try: import distributed config['pkg_distributed'] = True except: pass config['exa_relational'] = 'sqlite:///{}'.format(mkp(config['exa_root'], 'exa.sqlite')) existing_config = mkp(config['exa_root'], _filename) if config['exa_persistent'] and os.path.exists(existing_config): with open(existing_config) as f: econf = json.load(f) config['runlevel'] = econf['runlevel']
def save_config(): with open(mkp(config['exa_root'], _filename), 'w') as f: json.dump(config, f)
# -*- coding: utf-8 -*- # Copyright (c) 2015-2016, Exa Analytics Development Team # Distributed under the terms of the Apache License 2.0 ''' Exatomic Configuration ########################## This module adds dynamic (only) configuration parameters. For complete configuration options and usage see `exa`_. .. _exa: https://github.com/exa-analytics/exa ''' import os import shutil import platform from exa.utility import mkp from exa._config import config if platform.system().lower() == 'windows': # Get exatomic's root directory home = os.getenv('USERPROFILE') else: home = os.getenv('HOME') root = mkp(home, '.exa', mk=True) # Make exa root directory config['dynamic']['exatomic_pkgdir'] = os.path.dirname(__file__) if 'notebooks' in config['paths']['notebooks']: shutil.copyfile(mkp(config['dynamic']['exatomic_pkgdir'], '_static', 'exatomic_demo.ipynb'), mkp(root, 'notebooks', 'exatomic_demo.ipynb'))
def del_update(): ''' Reset update flags. ''' config['paths']['update'] = '0' config['js']['update'] = '0' config['db']['update'] = '0' config = configparser.ConfigParser() # Application configuration if platform.system().lower() == 'windows': # Get exa's root directory home = os.getenv('USERPROFILE') else: home = os.getenv('HOME') root = mkp(home, '.exa', mk=True) # Make exa root directory config_file = mkp(root, 'config') # Config file path pkg = os.path.dirname(__file__) # Package source path if os.path.exists(config_file): config.read(config_file) # Read in existing config else: config.read(mkp(pkg, '_static', 'config')) # Read in default config # paths if config['paths']['data'] == 'None': config['paths']['data'] = mkp(root, 'data', mk=True) if config['paths']['notebooks'] == 'None': config['paths']['notebooks'] = mkp(root, 'notebooks', mk=True) # log if config['log']['syslog'] == 'None': config['log']['syslog'] = mkp(root, 'sys.log') if config['log']['dblog'] == 'None':
def del_update(): """ Reset update flags. """ config['paths']['update'] = '0' config['js']['update'] = '0' config['db']['update'] = '0' config = configparser.ConfigParser() # Application configuration if platform.system().lower() == 'windows': # Get exa's root directory home = os.getenv('USERPROFILE') else: home = os.getenv('HOME') root = mkp(home, '.exa', mk=True) # Make exa root directory config_file = mkp(root, 'config') # Config file path pkg = os.path.dirname(__file__) # Package source path config.read(mkp(pkg, '_static', 'config')) # Read in default config if os.path.exists(config_file): stats = os.stat(config_file) if stats.st_size > 180: config.read(config_file) # Read in existing config # paths if config['paths']['data'] == 'None': config['paths']['data'] = mkp(root, 'data', mk=True) if config['paths']['notebooks'] == 'None': config['paths']['notebooks'] = mkp(root, 'notebooks', mk=True) shutil.copyfile(mkp(pkg, '_static', 'exa_demo.ipynb'), mkp(root, 'notebooks', 'exa_demo.ipynb')) mkp(config['paths']['data'], 'examples', mk=True) # Ensure the example dir is made
else: nxt = 0 try: lgfls = [fl.split(sep)[-1] for fl in glob(sep.join([savedir, "*png"]))] numbers = ["".join([c for c in fl if c.isdigit()]) for fl in lgfls] last = sorted([int(num) for num in numbers if num])[-1] nxt = last + 1 imgname = "{:06d}.png".format(nxt) except: imgname = "{:06d}.png".format(nxt) if path.isfile(sep.join([savedir, imgname])): print("Automatic file name generation failed. Use uni._widget.params['file_name']") return with open(sep.join([savedir, imgname]), "wb") as f: f.write(b64decode(data.replace("data:image/png;base64,", ""))) # TODO : this likely won"t work on windows but SHOULD automatically # crop the image to minimize whitespace of the final image. try: crop = " ".join(["convert -trim", imgname, imgname]) subprocess.call(crop, cwd=savedir, shell=True) except: pass if config['exatomic']['update'] == '1': verbose = True if config['log']['level'] != '0' else False pkg_nbext = mkp(config['dynamic']['exatomic_pkgdir'], "_nbextension") sys_nbext = mkp(jupyter_data_dir(), "nbextensions", "exa", "exatomic") install_notebook_widgets(pkg_nbext, sys_nbext, verbose) atexit.register(del_update)