Skip to content

Commit c08cb79

Browse files
authored
[fmt] Coordinates (#4856)
1 parent 29deccc commit c08cb79

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5819
-3670
lines changed

package/MDAnalysis/coordinates/CRD.py

+86-51
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ class CRDReader(base.SingleFrameReaderBase):
4545
Now returns a ValueError instead of FormatError.
4646
Frames now 0-based instead of 1-based.
4747
"""
48-
format = 'CRD'
49-
units = {'time': None, 'length': 'Angstrom'}
48+
49+
format = "CRD"
50+
units = {"time": None, "length": "Angstrom"}
5051

5152
def _read_first_frame(self):
5253
# EXT:
@@ -62,37 +63,47 @@ def _read_first_frame(self):
6263
extended = False
6364
natoms = 0
6465
for linenum, line in enumerate(crdfile):
65-
if line.strip().startswith('*') or line.strip() == "":
66+
if line.strip().startswith("*") or line.strip() == "":
6667
continue # ignore TITLE and empty lines
6768
fields = line.split()
6869
if len(fields) <= 2:
6970
# should be the natoms line
7071
natoms = int(fields[0])
71-
extended = (fields[-1] == 'EXT')
72+
extended = fields[-1] == "EXT"
7273
continue
7374
# process coordinates
7475
try:
7576
if extended:
76-
coords_list.append(np.array(line[45:100].split()[0:3], dtype=float))
77+
coords_list.append(
78+
np.array(line[45:100].split()[0:3], dtype=float)
79+
)
7780
else:
78-
coords_list.append(np.array(line[20:50].split()[0:3], dtype=float))
81+
coords_list.append(
82+
np.array(line[20:50].split()[0:3], dtype=float)
83+
)
7984
except Exception:
80-
errmsg = (f"Check CRD format at line {linenum}: "
81-
f"{line.rstrip()}")
85+
errmsg = (
86+
f"Check CRD format at line {linenum}: "
87+
f"{line.rstrip()}"
88+
)
8289
raise ValueError(errmsg) from None
8390

8491
self.n_atoms = len(coords_list)
8592

86-
self.ts = self._Timestep.from_coordinates(np.array(coords_list),
87-
**self._ts_kwargs)
93+
self.ts = self._Timestep.from_coordinates(
94+
np.array(coords_list), **self._ts_kwargs
95+
)
8896
self.ts.frame = 0 # 0-based frame number
8997
# if self.convert_units:
9098
# self.convert_pos_from_native(self.ts._pos) # in-place !
9199

92100
# sanity check
93101
if self.n_atoms != natoms:
94-
raise ValueError("Found %d coordinates in %r but the header claims that there "
95-
"should be %d coordinates." % (self.n_atoms, self.filename, natoms))
102+
raise ValueError(
103+
"Found %d coordinates in %r but the header claims that there "
104+
"should be %d coordinates."
105+
% (self.n_atoms, self.filename, natoms)
106+
)
96107

97108
def Writer(self, filename, **kwargs):
98109
"""Returns a CRDWriter for *filename*.
@@ -132,21 +143,26 @@ class CRDWriter(base.WriterBase):
132143
Files are now written in `wt` mode, and keep extensions, allowing
133144
for files to be written under compressed formats
134145
"""
135-
format = 'CRD'
136-
units = {'time': None, 'length': 'Angstrom'}
146+
147+
format = "CRD"
148+
units = {"time": None, "length": "Angstrom"}
137149

138150
fmt = {
139-
#crdtype = 'extended'
140-
#fortran_format = '(2I10,2X,A8,2X,A8,3F20.10,2X,A8,2X,A8,F20.10)'
141-
"ATOM_EXT": ("{serial:10d}{totRes:10d} {resname:<8.8s} {name:<8.8s}"
142-
"{pos[0]:20.10f}{pos[1]:20.10f}{pos[2]:20.10f} "
143-
"{chainID:<8.8s} {resSeq:<8d}{tempfactor:20.10f}\n"),
151+
# crdtype = 'extended'
152+
# fortran_format = '(2I10,2X,A8,2X,A8,3F20.10,2X,A8,2X,A8,F20.10)'
153+
"ATOM_EXT": (
154+
"{serial:10d}{totRes:10d} {resname:<8.8s} {name:<8.8s}"
155+
"{pos[0]:20.10f}{pos[1]:20.10f}{pos[2]:20.10f} "
156+
"{chainID:<8.8s} {resSeq:<8d}{tempfactor:20.10f}\n"
157+
),
144158
"NUMATOMS_EXT": "{0:10d} EXT\n",
145-
#crdtype = 'standard'
146-
#fortran_format = '(2I5,1X,A4,1X,A4,3F10.5,1X,A4,1X,A4,F10.5)'
147-
"ATOM": ("{serial:5d}{totRes:5d} {resname:<4.4s} {name:<4.4s}"
148-
"{pos[0]:10.5f}{pos[1]:10.5f}{pos[2]:10.5f} "
149-
"{chainID:<4.4s} {resSeq:<4d}{tempfactor:10.5f}\n"),
159+
# crdtype = 'standard'
160+
# fortran_format = '(2I5,1X,A4,1X,A4,3F10.5,1X,A4,1X,A4,F10.5)'
161+
"ATOM": (
162+
"{serial:5d}{totRes:5d} {resname:<4.4s} {name:<4.4s}"
163+
"{pos[0]:10.5f}{pos[1]:10.5f}{pos[2]:10.5f} "
164+
"{chainID:<4.4s} {resSeq:<4d}{tempfactor:10.5f}\n"
165+
),
150166
"TITLE": "* FRAME {frame} FROM {where}\n",
151167
"NUMATOMS": "{0:5d}\n",
152168
}
@@ -168,7 +184,7 @@ def __init__(self, filename, **kwargs):
168184
.. versionadded:: 2.2.0
169185
"""
170186

171-
self.filename = util.filename(filename, ext='crd', keep=True)
187+
self.filename = util.filename(filename, ext="crd", keep=True)
172188
self.crd = None
173189

174190
# account for explicit crd format, if requested
@@ -200,21 +216,22 @@ def write(self, selection, frame=None):
200216
except AttributeError:
201217
frame = 0 # should catch cases when we are analyzing a single PDB (?)
202218

203-
204219
atoms = selection.atoms # make sure to use atoms (Issue 46)
205-
coor = atoms.positions # can write from selection == Universe (Issue 49)
220+
coor = (
221+
atoms.positions
222+
) # can write from selection == Universe (Issue 49)
206223

207224
n_atoms = len(atoms)
208225
# Detect which format string we're using to output (EXT or not)
209226
# *len refers to how to truncate various things,
210227
# depending on output format!
211228
if self.extended or n_atoms > 99999:
212-
at_fmt = self.fmt['ATOM_EXT']
229+
at_fmt = self.fmt["ATOM_EXT"]
213230
serial_len = 10
214231
resid_len = 8
215232
totres_len = 10
216233
else:
217-
at_fmt = self.fmt['ATOM']
234+
at_fmt = self.fmt["ATOM"]
218235
serial_len = 5
219236
resid_len = 4
220237
totres_len = 5
@@ -223,11 +240,11 @@ def write(self, selection, frame=None):
223240
attrs = {}
224241
missing_topology = []
225242
for attr, default in (
226-
('resnames', itertools.cycle(('UNK',))),
227-
# Resids *must* be an array because we index it later
228-
('resids', np.ones(n_atoms, dtype=int)),
229-
('names', itertools.cycle(('X',))),
230-
('tempfactors', itertools.cycle((0.0,))),
243+
("resnames", itertools.cycle(("UNK",))),
244+
# Resids *must* be an array because we index it later
245+
("resids", np.ones(n_atoms, dtype=int)),
246+
("names", itertools.cycle(("X",))),
247+
("tempfactors", itertools.cycle((0.0,))),
231248
):
232249
try:
233250
attrs[attr] = getattr(atoms, attr)
@@ -236,48 +253,66 @@ def write(self, selection, frame=None):
236253
missing_topology.append(attr)
237254
# ChainIDs - Try ChainIDs first, fall back to Segids
238255
try:
239-
attrs['chainIDs'] = atoms.chainIDs
256+
attrs["chainIDs"] = atoms.chainIDs
240257
except (NoDataError, AttributeError):
241258
# try looking for segids instead
242259
try:
243-
attrs['chainIDs'] = atoms.segids
260+
attrs["chainIDs"] = atoms.segids
244261
except (NoDataError, AttributeError):
245-
attrs['chainIDs'] = itertools.cycle(('',))
262+
attrs["chainIDs"] = itertools.cycle(("",))
246263
missing_topology.append(attr)
247264
if missing_topology:
248265
warnings.warn(
249266
"Supplied AtomGroup was missing the following attributes: "
250267
"{miss}. These will be written with default values. "
251-
"".format(miss=', '.join(missing_topology)))
268+
"".format(miss=", ".join(missing_topology))
269+
)
252270

253-
with util.openany(self.filename, 'wt') as crd:
271+
with util.openany(self.filename, "wt") as crd:
254272
# Write Title
255-
crd.write(self.fmt['TITLE'].format(
256-
frame=frame, where=u.trajectory.filename))
273+
crd.write(
274+
self.fmt["TITLE"].format(
275+
frame=frame, where=u.trajectory.filename
276+
)
277+
)
257278
crd.write("*\n")
258279

259280
# Write NUMATOMS
260281
if self.extended or n_atoms > 99999:
261-
crd.write(self.fmt['NUMATOMS_EXT'].format(n_atoms))
282+
crd.write(self.fmt["NUMATOMS_EXT"].format(n_atoms))
262283
else:
263-
crd.write(self.fmt['NUMATOMS'].format(n_atoms))
284+
crd.write(self.fmt["NUMATOMS"].format(n_atoms))
264285

265286
# Write all atoms
266287

267288
current_resid = 1
268-
resids = attrs['resids']
289+
resids = attrs["resids"]
269290
for i, pos, resname, name, chainID, resid, tempfactor in zip(
270-
range(n_atoms), coor, attrs['resnames'], attrs['names'],
271-
attrs['chainIDs'], attrs['resids'], attrs['tempfactors']):
272-
if not i == 0 and resids[i] != resids[i-1]:
291+
range(n_atoms),
292+
coor,
293+
attrs["resnames"],
294+
attrs["names"],
295+
attrs["chainIDs"],
296+
attrs["resids"],
297+
attrs["tempfactors"],
298+
):
299+
if not i == 0 and resids[i] != resids[i - 1]:
273300
current_resid += 1
274301

275302
# Truncate numbers
276303
serial = util.ltruncate_int(i + 1, serial_len)
277304
resid = util.ltruncate_int(resid, resid_len)
278305
current_resid = util.ltruncate_int(current_resid, totres_len)
279306

280-
crd.write(at_fmt.format(
281-
serial=serial, totRes=current_resid, resname=resname,
282-
name=name, pos=pos, chainID=chainID,
283-
resSeq=resid, tempfactor=tempfactor))
307+
crd.write(
308+
at_fmt.format(
309+
serial=serial,
310+
totRes=current_resid,
311+
resname=resname,
312+
name=name,
313+
pos=pos,
314+
chainID=chainID,
315+
resSeq=resid,
316+
tempfactor=tempfactor,
317+
)
318+
)

package/MDAnalysis/coordinates/DMS.py

+21-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*-
2-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
2+
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
33
#
44
# MDAnalysis --- https://www.mdanalysis.org
55
# Copyright (c) 2006-2017 The MDAnalysis Development Team and contributors
@@ -46,29 +46,30 @@ class DMSReader(base.SingleFrameReaderBase):
4646
.. versionchanged:: 0.11.0
4747
Frames now 0-based instead of 1-based
4848
"""
49-
format = 'DMS'
50-
units = {'time': None, 'length': 'A', 'velocity': 'A/ps'}
49+
50+
format = "DMS"
51+
units = {"time": None, "length": "A", "velocity": "A/ps"}
5152

5253
def get_coordinates(self, cur):
53-
cur.execute('SELECT * FROM particle')
54+
cur.execute("SELECT * FROM particle")
5455
particles = cur.fetchall()
55-
return [(p['x'], p['y'], p['z']) for p in particles]
56+
return [(p["x"], p["y"], p["z"]) for p in particles]
5657

5758
def get_particle_by_columns(self, cur, columns=None):
5859
if columns is None:
59-
columns = ['x', 'y', 'z']
60-
cur.execute('SELECT * FROM particle')
60+
columns = ["x", "y", "z"]
61+
cur.execute("SELECT * FROM particle")
6162
particles = cur.fetchall()
6263
return [tuple([p[c] for c in columns]) for p in particles]
6364

6465
def get_global_cell(self, cur):
65-
cur.execute('SELECT * FROM global_cell')
66+
cur.execute("SELECT * FROM global_cell")
6667
rows = cur.fetchall()
6768
assert len(rows) == 3
6869
x = [row["x"] for row in rows]
6970
y = [row["y"] for row in rows]
7071
z = [row["z"] for row in rows]
71-
return {'x': x, 'y': y, 'z': z}
72+
return {"x": x, "y": y, "z": z}
7273

7374
def _read_first_frame(self):
7475
coords_list = None
@@ -85,7 +86,9 @@ def dict_factory(cursor, row):
8586
con.row_factory = dict_factory
8687
cur = con.cursor()
8788
coords_list = self.get_coordinates(cur)
88-
velocities_list = self.get_particle_by_columns(cur, columns=['vx', 'vy', 'vz'])
89+
velocities_list = self.get_particle_by_columns(
90+
cur, columns=["vx", "vy", "vz"]
91+
)
8992
unitcell = self.get_global_cell(cur)
9093

9194
if not coords_list:
@@ -99,15 +102,20 @@ def dict_factory(cursor, row):
99102
self.ts = self._Timestep.from_coordinates(
100103
np.array(coords_list, dtype=np.float32),
101104
velocities=velocities,
102-
**self._ts_kwargs)
105+
**self._ts_kwargs,
106+
)
103107
self.ts.frame = 0 # 0-based frame number
104108

105-
self.ts.dimensions = triclinic_box(unitcell['x'], unitcell['y'], unitcell['z'])
109+
self.ts.dimensions = triclinic_box(
110+
unitcell["x"], unitcell["y"], unitcell["z"]
111+
)
106112

107113
if self.convert_units:
108114
self.convert_pos_from_native(self.ts._pos) # in-place !
109115
if self.ts.dimensions is not None:
110-
self.convert_pos_from_native(self.ts.dimensions[:3]) # in-place !
116+
self.convert_pos_from_native(
117+
self.ts.dimensions[:3]
118+
) # in-place !
111119
if self.ts.has_velocities:
112120
# converts nm/ps to A/ps units
113121
self.convert_velocities_from_native(self.ts._velocities)

0 commit comments

Comments
 (0)