Skip to content

Commit 735b901

Browse files
authored
Merge pull request #78 from avmarchenko/master
Bugfixes for basis sets and version bump to 0.3.0
2 parents 153c521 + 81b57fa commit 735b901

6 files changed

Lines changed: 63 additions & 155 deletions

File tree

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Getting Started
2121
###################
2222
| |docs|
2323
| |gitter|
24+
| |doi|
2425
Documentation can be built using `sphinx`_:
2526

2627
.. code-block:: bash
@@ -81,3 +82,7 @@ Legal
8182
.. |lic| image:: http://img.shields.io/:license-apache-blue.svg?style=flat-square
8283
:target: http://www.apache.org/licenses/LICENSE-2.0
8384
:alt: License
85+
86+
.. |doi| image:: https://zenodo.org/badge/23807/exa-analytics/exatomic.svg
87+
:target: https://zenodo.org/badge/latestdoi/23807/exa-analytics/exatomic
88+
:alt: DOI

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, 14)
21+
__exatomic_version__ = (0, 3, 0)
2222
__version__ = '.'.join((str(v) for v in __exatomic_version__))
2323

2424

exatomic/algorithms/basis.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -241,14 +241,14 @@ def _overlap(x1, x2, y1, y2, z1, z2, l1, l2, m1, m2, n1, n2, N1, N2, alpha1, alp
241241
py2 = yp - y2
242242
pz2 = zp - z2
243243
pg12 = np.sqrt(np.pi / gamma)
244-
xIx = 0
245-
yIy = 0
246-
zIz = 0
244+
xix = 0
245+
yiy = 0
246+
ziz = 0
247247
ltot = l1 + l2
248248
mtot = m1 + m2
249249
ntot = n1 + n2
250250
if ltot == 0:
251-
xIx = pg12
251+
xix = pg12
252252
else:
253253
iii = (ltot - 1) // 2 if ltot % 2 != 0 else ltot // 2
254254
for i in range(iii):
@@ -263,9 +263,9 @@ def _overlap(x1, x2, y1, y2, z1, z2, l1, l2, m1, m2, n1, n2, N1, N2, alpha1, alp
263263
newt1 = fac(l1) / fac(j) / fac(l1 - j)
264264
newt2 = fac(l2) / fac(k) / fac(l2 - k)
265265
fk += newt1 * newt2 * (px1 ** (l1 - j)) * (px2 ** (l2 - k))
266-
xIx += prod * fk
266+
xix += prod * fk
267267
if mtot == 0:
268-
yIy = pg12
268+
yiy = pg12
269269
else:
270270
iii = (mtot - 1) // 2 if mtot % 2 != 0 else mtot // 2
271271
for i in range(iii):
@@ -280,9 +280,9 @@ def _overlap(x1, x2, y1, y2, z1, z2, l1, l2, m1, m2, n1, n2, N1, N2, alpha1, alp
280280
newt1 = fac(m1) / fac(j) / fac(m1 - j)
281281
newt2 = fac(m2) / fac(k) / fac(m2 - k)
282282
fk += newt1 * newt2 * (py1 ** (m1 - j)) * (py2 ** (m2 - k))
283-
yIy += prod * fk
283+
yiy += prod * fk
284284
if ntot == 0:
285-
zIz = pg12
285+
ziz = pg12
286286
else:
287287
iii = (ntot - 1) // 2 if ntot % 2 != 0 else ntot // 2
288288
for i in range(iii):
@@ -297,9 +297,9 @@ def _overlap(x1, x2, y1, y2, z1, z2, l1, l2, m1, m2, n1, n2, N1, N2, alpha1, alp
297297
newt1 = fac(n1) / fac(j) / fac(n1 - j)
298298
newt2 = fac(n2) / fac(k) / fac(n2 - k)
299299
fk += newt1 * newt2 * (pz1 ** (n1 - j)) * (pz2 ** (n2 - k))
300-
zIz += prod * fk
300+
ziz += prod * fk
301301
exponent = alpha1 * alpha2 * ab2 / gamma
302-
s12 = N1 * N2 * np.exp(-exponent) * xIx * yIy * zIz
302+
s12 = N1 * N2 * np.exp(-exponent) * xix * yiy * ziz
303303
return s12
304304

305305

exatomic/basis.py

Lines changed: 41 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,7 @@ def shells(self):
7070
Returns a list of all the shells in the basis set
7171
"""
7272
cols = [col.replace('bas_', '') for col in self if 'bas_' in col]
73-
shells = []
74-
for l in lorder:
75-
for ll in cols:
76-
if l == ll:
77-
shells.append(l)
78-
return shells
79-
80-
73+
return lorder[:len(cols)]
8174

8275

8376
class BasisSet(DataFrame):
@@ -151,31 +144,6 @@ class GaussianBasisSet(BasisSet):
151144
_precision = {'alpha': 8, 'd': 8}
152145
_categories = {'set': np.int64, 'L': np.int64}#, 'shell_function': np.int64}
153146

154-
# def _custom_traits(self):
155-
# g = self.grpd
156-
# alphas = g.apply(
157-
# lambda x: x.groupby('set').apply(
158-
# lambda y: y.groupby('shell_function').apply(
159-
# lambda z: z['alpha'].values).values)).to_json(orient='values')
160-
# #alphas = Unicode(''.join(['[', alphas, ']'])).tag(sync=True)
161-
# alphas = Unicode(alphas).tag(sync=True)
162-
#
163-
# ds = g.apply(
164-
# lambda x: x.groupby('set').apply(
165-
# lambda y: y.groupby('shell_function').apply(
166-
# lambda z: z['d'].values).values)).to_json(orient='values')
167-
# #ds = Unicode(''.join(['[', ds, ']'])).tag(sync=True)
168-
# ds = Unicode(ds).tag(sync=True)
169-
#
170-
# ls = g.apply(
171-
# lambda x: x.groupby('set').apply(
172-
# lambda y: y.groupby('shell_function').apply(
173-
# lambda z: z['L'].astype(np.int64).values).values)).to_json(orient='values')
174-
# #ls = Unicode(''.join(['[', ls, ']'])).tag(sync=True)
175-
# ls = Unicode(ls).tag(sync=True)
176-
#
177-
# return {'gaussianbasisset_d': ds, 'gaussianbasisset_l': ls,
178-
# 'gaussianbasisset_alpha': alphas}
179147

180148
def basis_count(self):
181149
"""
@@ -191,39 +159,40 @@ def _check(self):
191159
if 'N' not in self.columns:
192160
self._normalize()
193161

194-
# @classmethod
195-
# def expand(cls, universe, inplace=False):
196-
# '''
197-
# The minimum information specified by a basis set does not include
198-
# expansion due to degeneracy from m_l. This will expand the basis in a
199-
# systematic cartesian ordering convention to generate the full cartesian
200-
# basis. The universe argument must already have a universe with atom,
201-
# basis_set_summary, and gaussian_basis_set attributes.
202-
# '''
203-
# bases = universe.gaussian_basis_set[abs(universe.gaussian_basis_set['d']) > 0].groupby('set')
204-
# primdf = []
205-
# shfunc, func = -1, -1
206-
# for seht, x, y, z in zip(universe.atom['set'], universe.atom['x'],
207-
# universe.atom['y'], universe.atom['z']):
208-
# summ = universe.basis_set_summary.ix[seht]
209-
# b = bases.get_group(seht).groupby('shell_function')
210-
# for sh in range(len(b)):
211-
# prims = b.get_group(sh)
212-
# l = prims['L'].cat.as_ordered().max()
213-
# shfunc += 1
214-
# for l, m, n in enum_cartesian[l]:
215-
# func += 1
216-
# for alpha, d in zip(prims['alpha'], prims['d']):
217-
# primdf.append([x, y, z, alpha, d, l, m, n, l + m + n, sh, shfunc, func, seht])
218-
# primdf = pd.DataFrame(primdf)
219-
# primdf.columns = ['xa', 'ya', 'za', 'alpha', 'd', 'l', 'm', 'n', 'L', 'shell_function', 'shell', 'func', 'set']
220-
# if inplace:
221-
# universe.gaussian_basis_set = primdf
222-
# else:
223-
# return cls(primdf)
224-
225162

226163
class Primitive(DataFrame):
164+
"""
165+
Contains the required information to perform molecular integrals. Some
166+
repetition of data with GaussianBasisSet but for convenience also stored
167+
here.
168+
169+
Currently has the capability to compute the primitive overlap matrix
170+
and reduce the dimensionality to the contracted cartesian overlap
171+
matrix. Does not have the functionality to convert to the contracted
172+
spherical overlap matrix (the fully contracted basis set of routine
173+
gaussian type calculations).
174+
+-------------------+----------+-------------------------------------------+
175+
| Column | Type | Description |
176+
+===================+==========+===========================================+
177+
| xa | float | center in x direction of primitive |
178+
+-------------------+----------+-------------------------------------------+
179+
| ya | float | center in y direction of primitive |
180+
+-------------------+----------+-------------------------------------------+
181+
| za | float | center in z direction of primitive |
182+
+-------------------+----------+-------------------------------------------+
183+
| alpha | float | value of :math:`\\alpha`, the exponent |
184+
+-------------------+----------+-------------------------------------------+
185+
| d | float | value of the contraction coefficient |
186+
+-------------------+----------+-------------------------------------------+
187+
| l | int | pre-exponential power of x |
188+
+-------------------+----------+-------------------------------------------+
189+
| m | int | pre-exponential power of y |
190+
+-------------------+----------+-------------------------------------------+
191+
| n | int | pre-exponential power of z |
192+
+-------------------+----------+-------------------------------------------+
193+
| L | int/cat | sum of l + m + n |
194+
+-------------------+----------+-------------------------------------------+
195+
"""
227196
_columns = ['xa', 'ya', 'za', 'alpha', 'd', 'l', 'm', 'n', 'L']
228197
_indices = ['primitive']
229198
_categories = {'l': np.int64, 'm': np.int64, 'n': np.int64, 'L': np.int64}
@@ -277,9 +246,9 @@ def _spherical_from_cartesian(self):
277246
'''
278247
print('warning: this is not correct')
279248
lmax = self['L'].cat.as_ordered().max()
280-
primS = self.primitive_overlap().square()
249+
prim_ovl = self.primitive_overlap().square()
281250
cartprim, ls = self._cartesian_contraction_matrix(l=True)
282-
contracted = pd.DataFrame(np.dot(np.dot(cartprim.T, primS), cartprim))
251+
contracted = pd.DataFrame(np.dot(np.dot(cartprim.T, prim_ovl), cartprim))
283252
sh = solid_harmonics(lmax)
284253
sphtrans = car2sph_transform_matrices(sh, lmax)
285254
bfns = self.groupby('func')
@@ -308,9 +277,7 @@ def _spherical_from_cartesian(self):
308277

309278

310279
def primitive_overlap(self):
311-
'''
312-
Computes the complete primitive cartesian overlap matrix.
313-
'''
280+
"""Computes the complete primitive cartesian overlap matrix."""
314281
if 'N' not in self.columns:
315282
self._normalize()
316283
chi1, chi2, overlap = _wrap_overlap(self['xa'].values,
@@ -326,39 +293,16 @@ def primitive_overlap(self):
326293

327294

328295
def contracted_cartesian_overlap(self):
329-
primS = self.primitive_overlap().square()
296+
"""Returns the contracted cartesian overlap matrix."""
297+
prim_ovl = self.primitive_overlap().square()
330298
contprim = self._cartesian_contraction_matrix()
331-
square = pd.DataFrame(np.dot(np.dot(contprim.T, primS), contprim))
299+
square = pd.DataFrame(np.dot(np.dot(contprim.T, prim_ovl), contprim))
332300
return Overlap.from_square(square)
333301

334302
def contracted_spherical_overlap(self):
335303
return self._spherical_from_cartesian()
336304

337305

338-
# @classmethod
339-
# def from_universe(cls, universe, inplace=False):
340-
# bases = universe.gaussian_basis_set[abs(universe.gaussian_basis_set['d']) > 0].groupby('set')
341-
# primdf = []
342-
# shfunc, func = -1, -1
343-
# for seht, x, y, z in zip(universe.atom['set'], universe.atom['x'],
344-
# universe.atom['y'], universe.atom['z']):
345-
# summ = universe.basis_set_summary.ix[seht]
346-
# b = bases.get_group(seht).groupby('shell_function')
347-
# for sh in range(len(b)):
348-
# prims = b.get_group(sh)
349-
# l = prims['l'].cat.as_ordered().max()
350-
# shfunc += 1
351-
# for l, m, n in enum_cartesian[l]:
352-
# func += 1
353-
# for alpha, d in zip(prims['alpha'].values, prims['d'].values):
354-
# primdf.append([x, y, z, alpha, d, l, m, n, l + m + n, shfunc, func])
355-
# primdf = pd.DataFrame(primdf)
356-
# primdf.columns = ['xa', 'ya', 'za', 'alpha', 'd', 'l', 'm', 'n', 'L', 'shell', 'func']
357-
# if inplace:
358-
# universe.primitive = primdf
359-
# else:
360-
# return cls(primdf)
361-
362306
@classmethod
363307
def from_universe(cls, universe, inplace=False):
364308
'''
@@ -375,8 +319,8 @@ def from_universe(cls, universe, inplace=False):
375319
universe.atom['y'], universe.atom['z']):
376320
summ = universe.basis_set_summary.ix[seht]
377321
b = bases.get_group(seht).groupby('shell_function')
378-
for sh in range(len(b)):
379-
prims = b.get_group(sh)
322+
for sh, prims in b:
323+
if len(prims) == 0: continue
380324
l = prims['L'].cat.as_ordered().max()
381325
shfunc += 1
382326
for l, m, n in enum_cartesian[l]:
@@ -391,10 +335,6 @@ def from_universe(cls, universe, inplace=False):
391335
return cls(primdf)
392336

393337

394-
395-
396-
397-
398338
class BasisSetOrder(BasisSet):
399339
"""
400340
BasisSetOrder uniquely determines the basis function ordering scheme for
@@ -415,30 +355,6 @@ class BasisSetOrder(BasisSet):
415355
_index = 'chi'
416356
_categories = {'center': np.int64, 'symbol': str}
417357

418-
#class BasisSetMap(BasisSet):
419-
# """
420-
# BasisSetMap provides the auxiliary information about relational mapping
421-
# between the complete uncontracted primitive basis set and the resultant
422-
# contracted basis set within an :class:`~exatomic.universe.Universe`.
423-
#
424-
# +-------------------+----------+-------------------------------------------+
425-
# | Column | Type | Description |
426-
# +===================+==========+===========================================+
427-
# | tag | str | basis set identifier |
428-
# +-------------------+----------+-------------------------------------------+
429-
# | l | int | oribtal angular momentum quantum number |
430-
# +-------------------+----------+-------------------------------------------+
431-
# | nprim | int | number of primitives within shell |
432-
# +-------------------+----------+-------------------------------------------+
433-
# | nbasis | int | number of basis functions within shell |
434-
# +-------------------+----------+-------------------------------------------+
435-
# | degen | bool | False if cartesian, True if spherical |
436-
# +-------------------+----------+-------------------------------------------+
437-
# """
438-
# _columns = ['tag', 'nprim', 'nbasis', 'degen']
439-
# _indices = ['index']
440-
# #_categories = {'tag': str, 'shell': str, 'nbasis': np.int64, 'degen': bool}
441-
#
442358

443359
class Overlap(DataFrame):
444360
"""
@@ -522,18 +438,6 @@ class CartesianGTFOrder(DataFrame):
522438
_traits = ['l']
523439
_categories = {'l': np.int64, 'x': np.int64, 'y': np.int64, 'z': np.int64}
524440

525-
def _custom_traits(self):
526-
#print(self.groupby('l').apply(lambda y: y['x'].values))
527-
#print(self.groupby('l').apply(lambda y: y['x'].values).to_json(orient='values'))
528-
#cgto_x = self.groupby('l').apply(lambda x: x['x'].values).to_json(orient='values')
529-
#cgto_x = Unicode(''.join(['[', cgto_x, ']'])).tag(sync=True)
530-
#cgto_y = self.groupby('l').apply(lambda x: x['y'].values).to_json(orient='values')
531-
#cgto_y = Unicode(''.join(['[', cgto_y, ']'])).tag(sync=True)
532-
#cgto_z = self.groupby('l').apply(lambda x: x['z'].values).to_json(orient='values')
533-
#cgto_z = Unicode(''.join(['[', cgto_z, ']'])).tag(sync=True)
534-
#return {'cartesiangtforder_x': cgto_x, 'cartesiangtforder_y': cgto_y,
535-
# 'cartesiangtforder_z': cgto_z}
536-
return {}
537441

538442
@classmethod
539443
def from_lmax_order(cls, lmax, ordering_function):
@@ -579,13 +483,6 @@ class SphericalGTFOrder(DataFrame):
579483
_traits = ['l']
580484
_index = 'spherical_order'
581485

582-
def _custom_traits(self):
583-
sgto = self.groupby('frame').apply(lambda x: x.groupby('l').apply( lambda y: y['ml'].values))
584-
sgto = Unicode(sgto.to_json(orient='values')).tag(sync=True)
585-
return {'sphericalgtforder_ml': sgto}
586-
#Unicode('[' + self.groupby('l').apply(
587-
# lambda x: x['ml'].values).to_json(orient='values') + ']').tag(sync=True)}
588-
589486
@classmethod
590487
def from_lmax_order(cls, lmax, ordering_function):
591488
"""

exatomic/editor.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ def to_universe(self, name=None, description=None, meta=None):
3535
"""
3636
Convert the editor to a :class:`~exatomic.container.Universe` object.
3737
"""
38+
if self.meta is not None:
39+
if meta is not None:
40+
meta.update(self.meta)
41+
else:
42+
meta = self.meta
3843
kwargs = {'name': name, 'description': description, 'meta': meta}
3944
attrs = [attr.replace('parse_', '') for attr in vars(self.__class__).keys() if attr.startswith('parse_')]
4045
for attr in attrs:

exatomic/orbital.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class DensityMatrix(DataFrame):
160160
_index = 'index'
161161

162162
def square(self, frame=0):
163+
"""Returns a square dataframe of the density matrix."""
163164
denvec = self[self['frame'] == frame]['coefficient'].values
164165
square = pd.DataFrame(density_as_square(denvec))
165166
square.index.name = 'chi1'

0 commit comments

Comments
 (0)