Skip to content

Commit 5a63d7d

Browse files
authored
Merge pull request #8 from exa-analytics/master
T
2 parents f6f5f9f + 153c521 commit 5a63d7d

22 files changed

Lines changed: 320 additions & 148 deletions

.gitignore

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
# Byte-compiled / optimized / DLL files
2-
__pycache__
3-
_pycache__*
4-
__pycache__/*
5-
atomic/__pycache__/*
6-
atomic/qe/__pycahce__/*
7-
atomic/nwchem/__pycache__/*
2+
__pycache__/
83
*.py[cod]
94
*.nbc
105
*.nbi
@@ -59,7 +54,7 @@ coverage.xml
5954
*.log
6055

6156
# Sphinx documentation
62-
doc/build/*
57+
doc/build/
6358

6459
# PyBuilder
6560
target/*
@@ -70,3 +65,4 @@ target/*
7065
.settings/*
7166
*.swp
7267
.ipynb*
68+
*~

.travis.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ before_install:
88
- ./miniconda.sh -b
99
- export PATH=/home/travis/miniconda3/bin:$PATH
1010
- conda update --yes conda
11-
- wget https://github.com/exa-analytics/exa/archive/master.zip
12-
- unzip master.zip
1311
install:
14-
- conda install --yes python=$TRAVIS_PYTHON_VERSION atlas numpy scipy matplotlib pandas sqlalchemy networkx sympy seaborn jupyter notebook==4.1 ipywidgets==4.1 ipyparallel sphinx nose
15-
- pip install sphinxcontrib-autoanysrc codecov
16-
- cd exa-master && pip install .
12+
- conda install --yes python=$TRAVIS_PYTHON_VERSION
13+
- conda install -c conda-forge --yes jupyter notebook ipywidgets ipyparallel
14+
- conda config --add channels https://conda.anaconda.org/exaanalytics
15+
- conda install --yes exa
16+
- pip install sphinxcontrib-autoanysrc coverage codecov python-coveralls
17+
- python setup.py install
1718
- exa -uu
18-
- cd ../exa-master
1919
script:
2020
- nosetests --with-doctest --with-coverage
2121
after_success:
2222
- codecov
23+
- coveralls

README.rst

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,54 @@
11
| |logo|
2+
##################
3+
Installation
4+
##################
5+
| |conda|
6+
| |pypi|
7+
Exatomic is available through `anaconda`_,
8+
9+
.. code-block:: bash
10+
11+
conda install -c exaanalytics exatomic
12+
13+
or `pypi`_.
14+
15+
.. code-block:: bash
16+
17+
pip install exatomic
18+
19+
###################
20+
Getting Started
21+
###################
222
| |docs|
3-
| |gitter|
23+
| |gitter|
24+
Documentation can be built using `sphinx`_:
25+
26+
.. code-block:: bash
27+
28+
cd doc
29+
make html # or .\make.bat html
30+
31+
##################
32+
Status
33+
##################
434
| |build|
535
| |issues|
636
| |cov|
37+
38+
###############
39+
Legal
40+
###############
741
| |lic|
42+
| Copyright (c) 2015-2016, Exa Analytics Development Team
43+
| Distributed under the terms of the Apache License 2.0
44+
45+
.. _anaconda: https://www.continuum.io/downloads
46+
.. _pypi: https://pypi.python.org/pypi
47+
.. _sphinx: http://www.sphinx-doc.org/en/stable/
848

949
.. |logo| image:: doc/source/_static/logo.png
1050
:target: doc/source/_static/logo.png
11-
:alt: Exatomic
51+
:alt: Exatomic Analytics
1252

1353
.. |build| image:: https://travis-ci.org/exa-analytics/exatomic.svg?branch=master
1454
:target: https://travis-ci.org/exa-analytics/exatomic
@@ -18,47 +58,26 @@
1858
:target: http://exatomic.readthedocs.io/en/latest/?badge=latest
1959
:alt: Documentation Status
2060

21-
.. |gitter| image:: https://badges.gitter.im/exa-analytics/exatomic.svg
22-
:alt: Join the chat at https://gitter.im/exa-analytics/exatomic
23-
:target: https://gitter.im/exa-analytics/exatomic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
24-
61+
.. |conda| image:: https://anaconda.org/exaanalytics/exatomic/badges/installer/conda.svg
62+
:target: https://conda.anaconda.org/exaanalytics
63+
:alt: Anaconda Version
64+
65+
.. |pypi| image:: https://badge.fury.io/py/exatomic.svg
66+
:target: https://badge.fury.io/py/exatomic
67+
:alt: PyPI Version
68+
69+
.. |gitter| image:: https://badges.gitter.im/exa-analytics/exatomic.svg
70+
:target: https://gitter.im/exa-analytics/exatomic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
71+
:alt: Join the chat at https://gitter.im/exa-analytics/exatomic
72+
2573
.. |issues| image:: https://www.quantifiedcode.com/api/v1/project/99e4f26905194100ad4c27aba432ec4c/badge.svg
26-
:target: https://www.quantifiedcode.com/app/project/99e4f26905194100ad4c27aba432ec4c
27-
:alt: Code issues
74+
:target: https://www.quantifiedcode.com/app/project/99e4f26905194100ad4c27aba432ec4c
75+
:alt: Code issues
2876

29-
.. |cov| image:: https://codecov.io/gh/exa-analytics/exatomic/branch/master/graph/badge.svg
30-
:target: https://codecov.io/gh/exa-analytics/exatomic
77+
.. |cov| image:: https://coveralls.io/repos/github/exa-analytics/exatomic/badge.svg
78+
:target: https://coveralls.io/github/exa-analytics/exatomic
3179
:alt: Code Coverage
3280

3381
.. |lic| image:: http://img.shields.io/:license-apache-blue.svg?style=flat-square
3482
:target: http://www.apache.org/licenses/LICENSE-2.0
3583
:alt: License
36-
37-
Installation
38-
##################
39-
.. code-block:: bash
40-
41-
pip install exa
42-
pip install exatomic
43-
# Coming soon!
44-
# conda install exatomic
45-
46-
47-
Getting Started
48-
##################
49-
.. code-block:: bash
50-
51-
exa -u # Use the "-u" option on first run
52-
53-
54-
Documentation
55-
###################
56-
.. code-block:: bash
57-
58-
cd doc
59-
make html # .\make.bat html # Windows
60-
61-
Legal
62-
###############
63-
| Copyright (c) 2015-2016, Exa Analytics Development Team
64-
| Distributed under the terms of the Apache License 2.0

bld.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pip install sphinxcontrib-autoanysrc
2+
"%PYTHON%" setup.py install
3+
if errorlevel 1 exit 1

build.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
pip install sphinxcontrib-autoanysrc
3+
$PYTHON setup.py install

exatomic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
1919
.. _atomic: https://en.wikipedia.org/wiki/Atomic_units
2020
"""
21-
__exatomic_version__ = (0, 2, 12)
21+
__exatomic_version__ = (0, 2, 14)
2222
__version__ = '.'.join((str(v) for v in __exatomic_version__))
2323

2424

exatomic/_nbextension/app.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,28 @@ define([
178178
});
179179

180180
this.display = {
181+
'labels': false,
182+
'symbols': false,
181183
'cell': false,
182184
'axis': false,
183185
'spheres': false,
184186
};
185187
this.display['folder'] = this.gui.addFolder('display');
188+
this.display['labels_checkbox'] = this.display.folder.add(this.display, 'labels');
189+
this.display['symbols_checkbox'] = this.display.folder.add(this.display, 'symbols');
186190
this.display['cell_checkbox'] = this.display.folder.add(this.display, 'cell');
187191
this.display['axis_checkbox'] = this.display.folder.add(this.display, 'axis');
188192
this.display['spheres_checkbox'] = this.display.folder.add(this.display, 'spheres');
189193

194+
/*this.display.labels_checkbox.onFinishChange(function(value) {
195+
self.display.labels = value;
196+
if (value === false) {
197+
self.app3d.remove(self.label_meshes);
198+
} else {
199+
self.render_labels();
200+
};
201+
});*/
202+
190203
this.display.cell_checkbox.onFinishChange(function(value) {
191204
self.display.cell = value;
192205
if (value === false) {
@@ -539,6 +552,7 @@ define([
539552
this.app3d.remove_meshes(this.cell_meshes);
540553
this.cell_meshes = this.app3d.add_wireframe(vertices);
541554
};
555+
542556
};
543557

544558
return UniverseApp;

exatomic/algorithms/distance.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,46 @@ def periodic_pdist_euc_dxyz_idx(ux, uy, uz, rx, ry, rz, idxs, tol=10**-8):
101101
return dx, dy, dz, dr, idxi, idxj, px, py, pz
102102

103103

104+
def _compute(cx, cy, cz, rx, ry, rz, ox, oy, oz):
105+
"""
106+
"""
107+
l = [-1, 0, 1]
108+
m = len(cx)
109+
dx = np.empty((m, ), dtype=np.float64)
110+
dy = np.empty((m, ), dtype=np.float64)
111+
dz = np.empty((m, ), dtype=np.float64)
112+
px = np.empty((27, ), dtype=np.float64)
113+
py = np.empty((27, ), dtype=np.float64)
114+
pz = np.empty((27, ), dtype=np.float64)
115+
pr = np.empty((27, ), dtype=np.float64)
116+
h = 0
117+
for i in range(m):
118+
cxi = cx[i]
119+
cyi = cy[i]
120+
czi = cz[i]
121+
hh = 0
122+
for ii in l:
123+
for jj in l:
124+
for kk in l:
125+
sx = ii*rx
126+
sy = jj*ry
127+
sz = kk*rz
128+
xx = cxi + sx
129+
yy = cyi + sy
130+
zz = czi + sz
131+
pr[hh] = (ox - xx)**2 + (oy - yy)**2 + (oz - zz)**2
132+
px[hh] = sx
133+
py[hh] = sy
134+
pz[hh] = sz
135+
hh += 1
136+
hh = np.argmin(pr)
137+
dx[h] = px[hh]
138+
dy[h] = py[hh]
139+
dz[h] = pz[hh]
140+
h += 1
141+
return dx, dy, dz
142+
143+
104144
if config['dynamic']['numba'] == 'true':
105145
from numba import jit, vectorize
106146
from exa.math.vector.cartesian import magnitude_xyz
@@ -109,3 +149,4 @@ def periodic_pdist_euc_dxyz_idx(ux, uy, uz, rx, ry, rz, idxs, tol=10**-8):
109149
minimal_image_counts = jit(nopython=True, cache=True, nogil=True)(minimal_image_counts)
110150
minimal_image = vectorize(types3, nopython=True)(minimal_image)
111151
periodic_pdist_euc_dxyz_idx = jit(nopython=True, cache=True, nogil=True)(periodic_pdist_euc_dxyz_idx)
152+
_compute = jit(nopython=True, cache=True, nogil=True)(_compute)

exatomic/algorithms/neighbors.py

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
and :func:`~exatomic.molecule.Molecule.classify`.
1515
"""
1616
import numpy as np
17-
from exatomic.container import Universe
17+
import pandas as pd
18+
from exatomic.algorithms.distance import _compute
1819

1920

2021
def nearest_molecules(universe, n, sources, restrictions=None, how='atom',
@@ -46,13 +47,17 @@ def nearest_molecules(universe, n, sources, restrictions=None, how='atom',
4647
Returns:
4748
unis (dict): Dictionary of number of neighbors keys, universe values
4849
"""
49-
source_atoms, other_atoms, source_molecules, other_molecules, n = _slice_atoms_molecules(universe, sources, restrictions, how)
50+
source_atoms, other_atoms, source_molecules, other_molecules, n = _slice_atoms_molecules(universe, sources, restrictions, n)
5051
ordered_molecules, ordered_twos = _compute_neighbors_by_atom(universe, source_atoms, other_atoms, source_molecules)
51-
unis = {nn: _build_universe(universe, ordered_molecules, ordered_twos, nn) for nn in n}
52-
53-
54-
55-
52+
unis = {}
53+
if free_boundary == True:
54+
for nn in n:
55+
unis[nn] = _build_free_universe(universe, ordered_molecules,
56+
ordered_twos, nn, source_atoms,
57+
source_molecules)
58+
else:
59+
raise NotImplementedError()
60+
return unis
5661

5762

5863
def _slice_atoms_molecules(universe, sources, restrictions, n):
@@ -66,7 +71,7 @@ def _slice_atoms_molecules(universe, sources, restrictions, n):
6671
sources = [sources]
6772
if not isinstance(restrictions, list) and restrictions is not None:
6873
restrictions = [restrictions]
69-
if not isinstance(n, list):
74+
if isinstance(n, (int, np.int32, np.int64)):
7075
n = [n]
7176
symbols = universe.atom['symbol'].unique()
7277
classification = universe.molecule['classification'].unique()
@@ -135,12 +140,68 @@ def _compute_neighbors_by_com(universe, source_molecules, other_molecules):
135140
raise NotImplementedError()
136141

137142

143+
def _build_free_universe(universe, ordered_molecules, ordered_twos, n,
144+
source_atoms, source_molecules):
145+
"""
146+
"""
147+
molecule = np.concatenate([mcules[:n] for mcules in ordered_molecules])
148+
molecule = np.concatenate((molecule, source_molecules.index.tolist()))
149+
molecule = universe.molecule[universe.molecule.index.isin(molecule)].copy()
150+
atom = universe.atom[universe.atom['molecule'].isin(molecule.index)].copy()
151+
atom_two = universe.atom_two[(universe.atom_two['atom0'].isin(atom.index) &
152+
universe.atom_two['atom1'].isin(atom.index))].copy()
153+
frame = universe.frame[universe.frame.index.isin(atom['frame'])].copy()
154+
frame['periodic'] = False
155+
uni = universe.__class__(atom=atom, molecule=molecule, frame=frame, atom_two=atom_two)
156+
if universe.frame.is_periodic():
157+
uni.atom.update(universe.visual_atom)
158+
if 'cx' not in uni.molecule.columns:
159+
uni.compute_molecule_com()
160+
uni.atom._revert_categories()
161+
mapper = uni.atom.drop_duplicates('molecule').set_index('molecule')['frame']
162+
uni.atom._set_categories()
163+
uni.molecule['frame'] = uni.molecule.index.map(lambda x: mapper[x])
164+
sources = source_atoms.groupby('frame')
165+
groups = uni.molecule.groupby('frame')
166+
n = groups.ngroups
167+
dx = np.empty((n, ), dtype=np.ndarray)
168+
dy = np.empty((n, ), dtype=np.ndarray)
169+
dz = np.empty((n, ), dtype=np.ndarray)
170+
index = np.empty((n, ), dtype=np.ndarray)
171+
for i, (frame, group) in enumerate(groups):
172+
cx = group['cx'].values
173+
cy = group['cy'].values
174+
cz = group['cz'].values
175+
ccx, ccy, ccz = sources.get_group(frame)[['x', 'y', 'z']].mean().values
176+
# ccx, ccy, ccz = mcules.ix[mcules['classification'] == 'solute', ['cx', 'cy', 'cz']].values[0]
177+
rx, ry, rz = uni.frame.ix[frame, ['rx', 'ry', 'rz']].values
178+
dxf, dyf, dzf = _compute(cx, cy, cz, rx, ry, rz, ccx, ccy, ccz)
179+
dx[i] = dxf
180+
dy[i] = dyf
181+
dz[i] = dzf
182+
index[i] = group.index.values
183+
del uni.molecule['frame']
184+
dx = np.concatenate(dx)
185+
dy = np.concatenate(dy)
186+
dz = np.concatenate(dz)
187+
index = np.concatenate(index)
188+
df = pd.DataFrame.from_dict({'x': dx, 'y': dy, 'z': dz, 'molecule': index})
189+
df.set_index('molecule', inplace=True)
190+
for molecule in df.index:
191+
dx, dy, dz = df.ix[molecule].values
192+
uni.atom.ix[uni.atom['molecule'] == molecule, 'x'] += dx
193+
uni.atom.ix[uni.atom['molecule'] == molecule, 'y'] += dy
194+
uni.atom.ix[uni.atom['molecule'] == molecule, 'z'] += dz
195+
return uni
196+
197+
138198
def _build_universe(universe, ordered_molecules, ordered_twos, n):
139199
"""
140200
"""
201+
raise NotImplementedError()
141202
# TODO CONVERT TO A GENERIC AND COMPLETE SLICER
142-
molecules = np.concatenate([m[:n] for m in ordered_molecules.values])
143-
twos = np.concatenate([t[:n] for t in ordered_twos.values])
203+
molecules = np.concatenate([m[:n] for m in ordered_molecules])
204+
twos = np.concatenate([t[:n] for t in ordered_twos])
144205
atom = universe.atom[universe.atom['molecule'].isin(molecules)].copy().sort_index()
145206
two = universe.atom_two[universe.atom_two['atom0'].isin(atom.index) &
146207
universe.atom_two['atom1'].isin(atom.index)].copy().sort_index()

0 commit comments

Comments
 (0)