Skip to content

Commit

Permalink
Use attrs for IOData class
Browse files Browse the repository at this point in the history
Fixes theochem#73

Not all pylint exclusions can be removed, essentially due to pylint
bugs resulting in many false negatives, see

https://stackoverflow.com/questions/47972143/using-attr-with-pylint
pylint-dev/pylint#1694

The good solution is to disable all type-checking warnings of
pylint and to use a proper type checker like mypy instead.

Related changes:

- reaction_coordinate, ipoint, npoint, istep and nstep move to extra.
- many getattr and hasattr calls are replaced by nicer code.
- ArrayTypeCheckDescriptor is replaced by two simple functions.
- Document IOData.charge
- Bug got fixed in poscar format (gvecs)
  • Loading branch information
tovrstra committed May 13, 2019
1 parent ddeaa47 commit c5bcfdc
Show file tree
Hide file tree
Showing 26 changed files with 216 additions and 263 deletions.
2 changes: 1 addition & 1 deletion iodata/formats/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ def dump_one(f: TextIO, data: IOData):
attributes.
"""
title = getattr(data, 'title', 'Created with IOData')
title = data.title or 'Created with IOData'
_write_cube_header(f, title, data.atcoords, data.atnums, data.cube, data.atcorenums)
_write_cube_data(f, data.cube.data)
16 changes: 9 additions & 7 deletions iodata/formats/fchk.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ def load_many(lit: LineIterator) -> Iterator[dict]:
------
out
Output dictionary containing ``title``, ``atcoords``, ``atnums``,
``atcorenums``, ``ipoint``, ``npoint``, ``istep``, ``nstep``,
``gradient``, ``reaction_coordinate``, and ``energy``.
``atcorenums``, ``extra`` (with ``ipoint``, ``npoint``, ``istep``,
``nstep``), ``gradient``, ``reaction_coordinate``, and ``energy``.
Trajectories from a Gaussian optimization, relaxed scan or IRC calculation
are written in groups of frames, called "points" in the Gaussian world, e.g.
Expand Down Expand Up @@ -294,16 +294,18 @@ def load_many(lit: LineIterator) -> Iterator[dict]:
'title': fchk['title'],
'atnums': fchk["Atomic numbers"],
'atcorenums': fchk["Nuclear charges"],
'ipoint': ipoint,
'npoint': len(nsteps),
'istep': istep,
'nstep': nstep,
'energy': energy,
'atcoords': atcoords,
'atgradient': gradients,
'extra': {
'ipoint': ipoint,
'npoint': len(nsteps),
'istep': istep,
'nstep': nstep,
},
}
if prefix == "IRC point":
data['reaction_coordinate'] = recor
data['extra']['reaction_coordinate'] = recor
yield data


Expand Down
6 changes: 3 additions & 3 deletions iodata/formats/molden.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ def dump_one(f: TextIO, data: IOData):
"""
# Print the header
f.write('[Molden Format]\n')
if hasattr(data, 'title'):
if data.title is not None:
f.write('[Title]\n')
f.write(' {}\n'.format(data.title))

Expand All @@ -611,8 +611,8 @@ def dump_one(f: TextIO, data: IOData):
f.write('\n')

# Print the basis set
if not hasattr(data, 'obasis'):
raise IOError('A Gaussian orbital basis is required to write a molden input file.')
if data.obasis is None:
raise IOError('A Gaussian orbital basis is required to write a molden file.')
obasis = data.obasis

# Figure out the pure/Cartesian situation. Note that the Molden
Expand Down
13 changes: 6 additions & 7 deletions iodata/formats/molpro.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,18 @@ def dump_one(f: TextIO, data: IOData):
"""
one_mo = data.one_ints['core_mo']
two_mo = data.two_ints['two_mo']
nactive = one_mo.shape[0]
core_energy = getattr(data, 'core_energy', 0.0)
nelec = getattr(data, 'nelec', 0)
spinpol = getattr(data, 'spinpol', 0)

# Write header
nactive = one_mo.shape[0]
nelec = data.nelec or 0
spinpol = data.spinpol or 0
print(f' &FCI NORB={nactive:d},NELEC={nelec:d},MS2={spinpol:d},', file=f)
print(f" ORBSYM= {','.join('1' for v in range(nactive))},", file=f)
print(' ISYM=1', file=f)
print(' &END', file=f)

# Write integrals and core energy
two_mo = data.two_ints['two_mo']
for i in range(nactive): # pylint: disable=too-many-nested-blocks
for j in range(i + 1):
for k in range(nactive):
Expand All @@ -161,5 +160,5 @@ def dump_one(f: TextIO, data: IOData):
value = one_mo[i, j]
if value != 0.0:
print(f'{value:23.16e} {i+1:4d} {j+1:4d} {0:4d} {0:4d}', file=f)
if core_energy != 0.0:
print(f'{core_energy:23.16e} {0:4d} {0:4d} {0:4d} {0:4d}', file=f)
if data.core_energy is not None:
print(f'{data.core_energy:23.16e} {0:4d} {0:4d} {0:4d} {0:4d}', file=f)
5 changes: 3 additions & 2 deletions iodata/formats/poscar.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def dump_one(f: TextIO, data: IOData):
``cellvecs`` attributes. It may contain ``title`` attribute.
"""
print(getattr(data, 'title', 'Created with HORTON'), file=f)
print(data.title or 'Created with IOData', file=f)
print(' 1.00000000000000', file=f)

# Write cell vectors, each row is one vector in angstrom:
Expand All @@ -90,8 +90,9 @@ def dump_one(f: TextIO, data: IOData):
print('Direct', file=f)

# Write the coordinates
gvecs = np.linalg.inv(data.cellvecs).T
for uatnum in uatnums:
indexes = (data.atnums == uatnum).nonzero()[0]
for index in indexes:
row = np.dot(data.gvecs, data.atcoords[index])
row = np.dot(gvecs, data.atcoords[index])
print(f' {row[0]: 21.16f} {row[1]: 21.16f} {row[2]: 21.16f} F F F', file=f)
2 changes: 1 addition & 1 deletion iodata/formats/xyz.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def dump_one(f: TextIO, data: IOData):
"""
print(data.natom, file=f)
print(getattr(data, 'title', 'Created with IODATA module'), file=f)
print(data.title or 'Created with IOData', file=f)
for i in range(data.natom):
n = num2sym[data.atnums[i]]
x, y, z = data.atcoords[i] / angstrom
Expand Down
Loading

0 comments on commit c5bcfdc

Please sign in to comment.