Skip to content
This repository
  • 4 commits
  • 4 files changed
  • 0 comments
  • 1 contributor
12 chemlab/__init__.py
@@ -43,4 +43,14 @@ def display(molecule):
43 43 """
44 44 vw = Viewer()
45 45 vw.molecule = molecule
46   - vw.show()
  46 + vw.show()
  47 +
  48 +def animate(molecule_list, timestep=1.0/60):
  49 + """Display a list of Molecule instances *molecule_list* in an
  50 + animation, the *timestep* attribute sets the timestep in
  51 + seconds.
  52 +
  53 + """
  54 + vw = Viewer()
  55 + vw.animate(molecule_list, timestep)
  56 + vw.show()
17 chemlab/dataparsers/gamess.py
@@ -38,22 +38,31 @@ def get_property(self, prop):
38 38
39 39 def _parse_irc(self):
40 40 """Parse intrinsic reaction coordinate calculation.
41   -
  41 + returns a dictionary containing:
  42 +
  43 + geometries : a list of Molecule instances representing each point in the IRC
  44 + energies : a list of total energies (Hartree)
  45 + distances : distance from the starting point in mass-weighted coords (bohr \sqrt(amu))
42 46 """
43 47 irc_geoms = sections(re.escape("***** NEXT POINT ON IRC FOUND *****"),
44 48 re.escape("INTERNUCLEAR DISTANCES (ANGS.)"),
45 49 self.text)
46 50
47 51 # get and store the energy
48   - energies = [entry.splitlines()[5] for entry in irc_geoms]
  52 + energies = [entry.splitlines()[5] for entry in irc_geoms] # The total energy line
49 53 energies = [float(entry.split()[3]) for entry in energies]
  54 +
  55 + # get and store the distance
  56 + distances = [entry.splitlines()[4] for entry in irc_geoms] # The path distance line
  57 + distances = [float(entry.split()[5]) for entry in distances]
50 58
51 59 # strip the garbage
52 60 irc_geoms = ['\n'.join(i.splitlines()[11:-1]) for i in irc_geoms]
53 61 irc_geoms = [self._parse_geometry(i) for i in irc_geoms]
54 62
55 63 return {"geometries": irc_geoms,
56   - "energies": energies}
  64 + "energies": energies,
  65 + "distances": distances}
57 66
58 67 def _parse_geometry(self, geom):
59 68 """Parse a geometry string and return Molecule object from
@@ -65,7 +74,7 @@ def _parse_geometry(self, geom):
65 74 sym, atno, x, y, z = line.split()
66 75 atoms.append(Atom(i, sym, [float(x), float(y), float(z)]))
67 76
68   - return Molecule(atoms, [])
  77 + return Molecule(atoms)
69 78
70 79 def parse_optimize(self):
71 80 """Parse the ouput resulted of a geometry optimization. Or a
497 distribute_setup.py
... ... @@ -0,0 +1,497 @@
  1 +#!python
  2 +"""Bootstrap distribute installation
  3 +
  4 +If you want to use setuptools in your package's setup.py, just include this
  5 +file in the same directory with it, and add this to the top of your setup.py::
  6 +
  7 + from distribute_setup import use_setuptools
  8 + use_setuptools()
  9 +
  10 +If you want to require a specific version of setuptools, set a download
  11 +mirror, or use an alternate download directory, you can do so by supplying
  12 +the appropriate options to ``use_setuptools()``.
  13 +
  14 +This file can also be run as a script to install or upgrade setuptools.
  15 +"""
  16 +import os
  17 +import sys
  18 +import time
  19 +import fnmatch
  20 +import tempfile
  21 +import tarfile
  22 +from distutils import log
  23 +
  24 +try:
  25 + from site import USER_SITE
  26 +except ImportError:
  27 + USER_SITE = None
  28 +
  29 +try:
  30 + import subprocess
  31 +
  32 + def _python_cmd(*args):
  33 + args = (sys.executable,) + args
  34 + return subprocess.call(args) == 0
  35 +
  36 +except ImportError:
  37 + # will be used for python 2.3
  38 + def _python_cmd(*args):
  39 + args = (sys.executable,) + args
  40 + # quoting arguments if windows
  41 + if sys.platform == 'win32':
  42 + def quote(arg):
  43 + if ' ' in arg:
  44 + return '"%s"' % arg
  45 + return arg
  46 + args = [quote(arg) for arg in args]
  47 + return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
  48 +
  49 +DEFAULT_VERSION = "0.6.27"
  50 +DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
  51 +SETUPTOOLS_FAKED_VERSION = "0.6c11"
  52 +
  53 +SETUPTOOLS_PKG_INFO = """\
  54 +Metadata-Version: 1.0
  55 +Name: setuptools
  56 +Version: %s
  57 +Summary: xxxx
  58 +Home-page: xxx
  59 +Author: xxx
  60 +Author-email: xxx
  61 +License: xxx
  62 +Description: xxx
  63 +""" % SETUPTOOLS_FAKED_VERSION
  64 +
  65 +
  66 +def _install(tarball, install_args=()):
  67 + # extracting the tarball
  68 + tmpdir = tempfile.mkdtemp()
  69 + log.warn('Extracting in %s', tmpdir)
  70 + old_wd = os.getcwd()
  71 + try:
  72 + os.chdir(tmpdir)
  73 + tar = tarfile.open(tarball)
  74 + _extractall(tar)
  75 + tar.close()
  76 +
  77 + # going in the directory
  78 + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
  79 + os.chdir(subdir)
  80 + log.warn('Now working in %s', subdir)
  81 +
  82 + # installing
  83 + log.warn('Installing Distribute')
  84 + if not _python_cmd('setup.py', 'install', *install_args):
  85 + log.warn('Something went wrong during the installation.')
  86 + log.warn('See the error message above.')
  87 + finally:
  88 + os.chdir(old_wd)
  89 +
  90 +
  91 +def _build_egg(egg, tarball, to_dir):
  92 + # extracting the tarball
  93 + tmpdir = tempfile.mkdtemp()
  94 + log.warn('Extracting in %s', tmpdir)
  95 + old_wd = os.getcwd()
  96 + try:
  97 + os.chdir(tmpdir)
  98 + tar = tarfile.open(tarball)
  99 + _extractall(tar)
  100 + tar.close()
  101 +
  102 + # going in the directory
  103 + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
  104 + os.chdir(subdir)
  105 + log.warn('Now working in %s', subdir)
  106 +
  107 + # building an egg
  108 + log.warn('Building a Distribute egg in %s', to_dir)
  109 + _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
  110 +
  111 + finally:
  112 + os.chdir(old_wd)
  113 + # returning the result
  114 + log.warn(egg)
  115 + if not os.path.exists(egg):
  116 + raise IOError('Could not build the egg.')
  117 +
  118 +
  119 +def _do_download(version, download_base, to_dir, download_delay):
  120 + egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
  121 + % (version, sys.version_info[0], sys.version_info[1]))
  122 + if not os.path.exists(egg):
  123 + tarball = download_setuptools(version, download_base,
  124 + to_dir, download_delay)
  125 + _build_egg(egg, tarball, to_dir)
  126 + sys.path.insert(0, egg)
  127 + import setuptools
  128 + setuptools.bootstrap_install_from = egg
  129 +
  130 +
  131 +def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
  132 + to_dir=os.curdir, download_delay=15, no_fake=True):
  133 + # making sure we use the absolute path
  134 + to_dir = os.path.abspath(to_dir)
  135 + was_imported = 'pkg_resources' in sys.modules or \
  136 + 'setuptools' in sys.modules
  137 + try:
  138 + try:
  139 + import pkg_resources
  140 + if not hasattr(pkg_resources, '_distribute'):
  141 + if not no_fake:
  142 + _fake_setuptools()
  143 + raise ImportError
  144 + except ImportError:
  145 + return _do_download(version, download_base, to_dir, download_delay)
  146 + try:
  147 + pkg_resources.require("distribute>="+version)
  148 + return
  149 + except pkg_resources.VersionConflict:
  150 + e = sys.exc_info()[1]
  151 + if was_imported:
  152 + sys.stderr.write(
  153 + "The required version of distribute (>=%s) is not available,\n"
  154 + "and can't be installed while this script is running. Please\n"
  155 + "install a more recent version first, using\n"
  156 + "'easy_install -U distribute'."
  157 + "\n\n(Currently using %r)\n" % (version, e.args[0]))
  158 + sys.exit(2)
  159 + else:
  160 + del pkg_resources, sys.modules['pkg_resources'] # reload ok
  161 + return _do_download(version, download_base, to_dir,
  162 + download_delay)
  163 + except pkg_resources.DistributionNotFound:
  164 + return _do_download(version, download_base, to_dir,
  165 + download_delay)
  166 + finally:
  167 + if not no_fake:
  168 + _create_fake_setuptools_pkg_info(to_dir)
  169 +
  170 +def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
  171 + to_dir=os.curdir, delay=15):
  172 + """Download distribute from a specified location and return its filename
  173 +
  174 + `version` should be a valid distribute version number that is available
  175 + as an egg for download under the `download_base` URL (which should end
  176 + with a '/'). `to_dir` is the directory where the egg will be downloaded.
  177 + `delay` is the number of seconds to pause before an actual download
  178 + attempt.
  179 + """
  180 + # making sure we use the absolute path
  181 + to_dir = os.path.abspath(to_dir)
  182 + try:
  183 + from urllib.request import urlopen
  184 + except ImportError:
  185 + from urllib2 import urlopen
  186 + tgz_name = "distribute-%s.tar.gz" % version
  187 + url = download_base + tgz_name
  188 + saveto = os.path.join(to_dir, tgz_name)
  189 + src = dst = None
  190 + if not os.path.exists(saveto): # Avoid repeated downloads
  191 + try:
  192 + log.warn("Downloading %s", url)
  193 + src = urlopen(url)
  194 + # Read/write all in one block, so we don't create a corrupt file
  195 + # if the download is interrupted.
  196 + data = src.read()
  197 + dst = open(saveto, "wb")
  198 + dst.write(data)
  199 + finally:
  200 + if src:
  201 + src.close()
  202 + if dst:
  203 + dst.close()
  204 + return os.path.realpath(saveto)
  205 +
  206 +def _no_sandbox(function):
  207 + def __no_sandbox(*args, **kw):
  208 + try:
  209 + from setuptools.sandbox import DirectorySandbox
  210 + if not hasattr(DirectorySandbox, '_old'):
  211 + def violation(*args):
  212 + pass
  213 + DirectorySandbox._old = DirectorySandbox._violation
  214 + DirectorySandbox._violation = violation
  215 + patched = True
  216 + else:
  217 + patched = False
  218 + except ImportError:
  219 + patched = False
  220 +
  221 + try:
  222 + return function(*args, **kw)
  223 + finally:
  224 + if patched:
  225 + DirectorySandbox._violation = DirectorySandbox._old
  226 + del DirectorySandbox._old
  227 +
  228 + return __no_sandbox
  229 +
  230 +def _patch_file(path, content):
  231 + """Will backup the file then patch it"""
  232 + existing_content = open(path).read()
  233 + if existing_content == content:
  234 + # already patched
  235 + log.warn('Already patched.')
  236 + return False
  237 + log.warn('Patching...')
  238 + _rename_path(path)
  239 + f = open(path, 'w')
  240 + try:
  241 + f.write(content)
  242 + finally:
  243 + f.close()
  244 + return True
  245 +
  246 +_patch_file = _no_sandbox(_patch_file)
  247 +
  248 +def _same_content(path, content):
  249 + return open(path).read() == content
  250 +
  251 +def _rename_path(path):
  252 + new_name = path + '.OLD.%s' % time.time()
  253 + log.warn('Renaming %s into %s', path, new_name)
  254 + os.rename(path, new_name)
  255 + return new_name
  256 +
  257 +def _remove_flat_installation(placeholder):
  258 + if not os.path.isdir(placeholder):
  259 + log.warn('Unkown installation at %s', placeholder)
  260 + return False
  261 + found = False
  262 + for file in os.listdir(placeholder):
  263 + if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
  264 + found = True
  265 + break
  266 + if not found:
  267 + log.warn('Could not locate setuptools*.egg-info')
  268 + return
  269 +
  270 + log.warn('Removing elements out of the way...')
  271 + pkg_info = os.path.join(placeholder, file)
  272 + if os.path.isdir(pkg_info):
  273 + patched = _patch_egg_dir(pkg_info)
  274 + else:
  275 + patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
  276 +
  277 + if not patched:
  278 + log.warn('%s already patched.', pkg_info)
  279 + return False
  280 + # now let's move the files out of the way
  281 + for element in ('setuptools', 'pkg_resources.py', 'site.py'):
  282 + element = os.path.join(placeholder, element)
  283 + if os.path.exists(element):
  284 + _rename_path(element)
  285 + else:
  286 + log.warn('Could not find the %s element of the '
  287 + 'Setuptools distribution', element)
  288 + return True
  289 +
  290 +_remove_flat_installation = _no_sandbox(_remove_flat_installation)
  291 +
  292 +def _after_install(dist):
  293 + log.warn('After install bootstrap.')
  294 + placeholder = dist.get_command_obj('install').install_purelib
  295 + _create_fake_setuptools_pkg_info(placeholder)
  296 +
  297 +def _create_fake_setuptools_pkg_info(placeholder):
  298 + if not placeholder or not os.path.exists(placeholder):
  299 + log.warn('Could not find the install location')
  300 + return
  301 + pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
  302 + setuptools_file = 'setuptools-%s-py%s.egg-info' % \
  303 + (SETUPTOOLS_FAKED_VERSION, pyver)
  304 + pkg_info = os.path.join(placeholder, setuptools_file)
  305 + if os.path.exists(pkg_info):
  306 + log.warn('%s already exists', pkg_info)
  307 + return
  308 +
  309 + if not os.access(pkg_info, os.W_OK):
  310 + log.warn("Don't have permissions to write %s, skipping", pkg_info)
  311 +
  312 + log.warn('Creating %s', pkg_info)
  313 + f = open(pkg_info, 'w')
  314 + try:
  315 + f.write(SETUPTOOLS_PKG_INFO)
  316 + finally:
  317 + f.close()
  318 +
  319 + pth_file = os.path.join(placeholder, 'setuptools.pth')
  320 + log.warn('Creating %s', pth_file)
  321 + f = open(pth_file, 'w')
  322 + try:
  323 + f.write(os.path.join(os.curdir, setuptools_file))
  324 + finally:
  325 + f.close()
  326 +
  327 +_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
  328 +
  329 +def _patch_egg_dir(path):
  330 + # let's check if it's already patched
  331 + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
  332 + if os.path.exists(pkg_info):
  333 + if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
  334 + log.warn('%s already patched.', pkg_info)
  335 + return False
  336 + _rename_path(path)
  337 + os.mkdir(path)
  338 + os.mkdir(os.path.join(path, 'EGG-INFO'))
  339 + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
  340 + f = open(pkg_info, 'w')
  341 + try:
  342 + f.write(SETUPTOOLS_PKG_INFO)
  343 + finally:
  344 + f.close()
  345 + return True
  346 +
  347 +_patch_egg_dir = _no_sandbox(_patch_egg_dir)
  348 +
  349 +def _before_install():
  350 + log.warn('Before install bootstrap.')
  351 + _fake_setuptools()
  352 +
  353 +
  354 +def _under_prefix(location):
  355 + if 'install' not in sys.argv:
  356 + return True
  357 + args = sys.argv[sys.argv.index('install')+1:]
  358 + for index, arg in enumerate(args):
  359 + for option in ('--root', '--prefix'):
  360 + if arg.startswith('%s=' % option):
  361 + top_dir = arg.split('root=')[-1]
  362 + return location.startswith(top_dir)
  363 + elif arg == option:
  364 + if len(args) > index:
  365 + top_dir = args[index+1]
  366 + return location.startswith(top_dir)
  367 + if arg == '--user' and USER_SITE is not None:
  368 + return location.startswith(USER_SITE)
  369 + return True
  370 +
  371 +
  372 +def _fake_setuptools():
  373 + log.warn('Scanning installed packages')
  374 + try:
  375 + import pkg_resources
  376 + except ImportError:
  377 + # we're cool
  378 + log.warn('Setuptools or Distribute does not seem to be installed.')
  379 + return
  380 + ws = pkg_resources.working_set
  381 + try:
  382 + setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
  383 + replacement=False))
  384 + except TypeError:
  385 + # old distribute API
  386 + setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
  387 +
  388 + if setuptools_dist is None:
  389 + log.warn('No setuptools distribution found')
  390 + return
  391 + # detecting if it was already faked
  392 + setuptools_location = setuptools_dist.location
  393 + log.warn('Setuptools installation detected at %s', setuptools_location)
  394 +
  395 + # if --root or --preix was provided, and if
  396 + # setuptools is not located in them, we don't patch it
  397 + if not _under_prefix(setuptools_location):
  398 + log.warn('Not patching, --root or --prefix is installing Distribute'
  399 + ' in another location')
  400 + return
  401 +
  402 + # let's see if its an egg
  403 + if not setuptools_location.endswith('.egg'):
  404 + log.warn('Non-egg installation')
  405 + res = _remove_flat_installation(setuptools_location)
  406 + if not res:
  407 + return
  408 + else:
  409 + log.warn('Egg installation')
  410 + pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
  411 + if (os.path.exists(pkg_info) and
  412 + _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
  413 + log.warn('Already patched.')
  414 + return
  415 + log.warn('Patching...')
  416 + # let's create a fake egg replacing setuptools one
  417 + res = _patch_egg_dir(setuptools_location)
  418 + if not res:
  419 + return
  420 + log.warn('Patched done.')
  421 + _relaunch()
  422 +
  423 +
  424 +def _relaunch():
  425 + log.warn('Relaunching...')
  426 + # we have to relaunch the process
  427 + # pip marker to avoid a relaunch bug
  428 + if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
  429 + sys.argv[0] = 'setup.py'
  430 + args = [sys.executable] + sys.argv
  431 + sys.exit(subprocess.call(args))
  432 +
  433 +
  434 +def _extractall(self, path=".", members=None):
  435 + """Extract all members from the archive to the current working
  436 + directory and set owner, modification time and permissions on
  437 + directories afterwards. `path' specifies a different directory
  438 + to extract to. `members' is optional and must be a subset of the
  439 + list returned by getmembers().
  440 + """
  441 + import copy
  442 + import operator
  443 + from tarfile import ExtractError
  444 + directories = []
  445 +
  446 + if members is None:
  447 + members = self
  448 +
  449 + for tarinfo in members:
  450 + if tarinfo.isdir():
  451 + # Extract directories with a safe mode.
  452 + directories.append(tarinfo)
  453 + tarinfo = copy.copy(tarinfo)
  454 + tarinfo.mode = 448 # decimal for oct 0700
  455 + self.extract(tarinfo, path)
  456 +
  457 + # Reverse sort directories.
  458 + if sys.version_info < (2, 4):
  459 + def sorter(dir1, dir2):
  460 + return cmp(dir1.name, dir2.name)
  461 + directories.sort(sorter)
  462 + directories.reverse()
  463 + else:
  464 + directories.sort(key=operator.attrgetter('name'), reverse=True)
  465 +
  466 + # Set correct owner, mtime and filemode on directories.
  467 + for tarinfo in directories:
  468 + dirpath = os.path.join(path, tarinfo.name)
  469 + try:
  470 + self.chown(tarinfo, dirpath)
  471 + self.utime(tarinfo, dirpath)
  472 + self.chmod(tarinfo, dirpath)
  473 + except ExtractError:
  474 + e = sys.exc_info()[1]
  475 + if self.errorlevel > 1:
  476 + raise
  477 + else:
  478 + self._dbg(1, "tarfile: %s" % e)
  479 +
  480 +def _build_install_args(argv):
  481 + install_args = []
  482 + user_install = '--user' in argv
  483 + if user_install and sys.version_info < (2,6):
  484 + log.warn("--user requires Python 2.6 or later")
  485 + raise SystemExit(1)
  486 + if user_install:
  487 + install_args.append('--user')
  488 + return install_args
  489 +
  490 +def main(argv, version=DEFAULT_VERSION):
  491 + """Install or upgrade setuptools and EasyInstall"""
  492 + tarball = download_setuptools()
  493 + _install(tarball, _build_install_args(argv))
  494 +
  495 +
  496 +if __name__ == '__main__':
  497 + main(sys.argv[1:])
19 setup.py
... ... @@ -0,0 +1,19 @@
  1 +from distribute_setup import use_setuptools
  2 +use_setuptools()
  3 +from setuptools import setup, find_packages
  4 +
  5 +setup(
  6 + name = "chemlab",
  7 + version = "0.1",
  8 + packages = find_packages(),
  9 + install_requires = ["pyglet", "numpy"],
  10 + dependency_links = [
  11 + "http://pyglet.googlecode.com/files/pyglet-1.1.4.tar.gz"
  12 + ],
  13 + author = "Gabriele Lanaro",
  14 + author_email = "gabriele.lanaro@gmail.com",
  15 + description = "Theoretical chemistry utilities for humans",
  16 + license = "GPL2",
  17 + keywords = "chemistry molecular_viewer",
  18 + url = "https://github.com/chemlab/chemlab"
  19 +)

No commit comments for this range

Something went wrong with that request. Please try again.