@@ -45,8 +45,9 @@ class CRDReader(base.SingleFrameReaderBase):
45
45
Now returns a ValueError instead of FormatError.
46
46
Frames now 0-based instead of 1-based.
47
47
"""
48
- format = 'CRD'
49
- units = {'time' : None , 'length' : 'Angstrom' }
48
+
49
+ format = "CRD"
50
+ units = {"time" : None , "length" : "Angstrom" }
50
51
51
52
def _read_first_frame (self ):
52
53
# EXT:
@@ -62,37 +63,47 @@ def _read_first_frame(self):
62
63
extended = False
63
64
natoms = 0
64
65
for linenum , line in enumerate (crdfile ):
65
- if line .strip ().startswith ('*' ) or line .strip () == "" :
66
+ if line .strip ().startswith ("*" ) or line .strip () == "" :
66
67
continue # ignore TITLE and empty lines
67
68
fields = line .split ()
68
69
if len (fields ) <= 2 :
69
70
# should be the natoms line
70
71
natoms = int (fields [0 ])
71
- extended = ( fields [- 1 ] == ' EXT' )
72
+ extended = fields [- 1 ] == " EXT"
72
73
continue
73
74
# process coordinates
74
75
try :
75
76
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
+ )
77
80
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
+ )
79
84
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
+ )
82
89
raise ValueError (errmsg ) from None
83
90
84
91
self .n_atoms = len (coords_list )
85
92
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
+ )
88
96
self .ts .frame = 0 # 0-based frame number
89
97
# if self.convert_units:
90
98
# self.convert_pos_from_native(self.ts._pos) # in-place !
91
99
92
100
# sanity check
93
101
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
+ )
96
107
97
108
def Writer (self , filename , ** kwargs ):
98
109
"""Returns a CRDWriter for *filename*.
@@ -132,21 +143,26 @@ class CRDWriter(base.WriterBase):
132
143
Files are now written in `wt` mode, and keep extensions, allowing
133
144
for files to be written under compressed formats
134
145
"""
135
- format = 'CRD'
136
- units = {'time' : None , 'length' : 'Angstrom' }
146
+
147
+ format = "CRD"
148
+ units = {"time" : None , "length" : "Angstrom" }
137
149
138
150
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
+ ),
144
158
"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
+ ),
150
166
"TITLE" : "* FRAME {frame} FROM {where}\n " ,
151
167
"NUMATOMS" : "{0:5d}\n " ,
152
168
}
@@ -168,7 +184,7 @@ def __init__(self, filename, **kwargs):
168
184
.. versionadded:: 2.2.0
169
185
"""
170
186
171
- self .filename = util .filename (filename , ext = ' crd' , keep = True )
187
+ self .filename = util .filename (filename , ext = " crd" , keep = True )
172
188
self .crd = None
173
189
174
190
# account for explicit crd format, if requested
@@ -200,21 +216,22 @@ def write(self, selection, frame=None):
200
216
except AttributeError :
201
217
frame = 0 # should catch cases when we are analyzing a single PDB (?)
202
218
203
-
204
219
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)
206
223
207
224
n_atoms = len (atoms )
208
225
# Detect which format string we're using to output (EXT or not)
209
226
# *len refers to how to truncate various things,
210
227
# depending on output format!
211
228
if self .extended or n_atoms > 99999 :
212
- at_fmt = self .fmt [' ATOM_EXT' ]
229
+ at_fmt = self .fmt [" ATOM_EXT" ]
213
230
serial_len = 10
214
231
resid_len = 8
215
232
totres_len = 10
216
233
else :
217
- at_fmt = self .fmt [' ATOM' ]
234
+ at_fmt = self .fmt [" ATOM" ]
218
235
serial_len = 5
219
236
resid_len = 4
220
237
totres_len = 5
@@ -223,11 +240,11 @@ def write(self, selection, frame=None):
223
240
attrs = {}
224
241
missing_topology = []
225
242
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 ,))),
231
248
):
232
249
try :
233
250
attrs [attr ] = getattr (atoms , attr )
@@ -236,48 +253,66 @@ def write(self, selection, frame=None):
236
253
missing_topology .append (attr )
237
254
# ChainIDs - Try ChainIDs first, fall back to Segids
238
255
try :
239
- attrs [' chainIDs' ] = atoms .chainIDs
256
+ attrs [" chainIDs" ] = atoms .chainIDs
240
257
except (NoDataError , AttributeError ):
241
258
# try looking for segids instead
242
259
try :
243
- attrs [' chainIDs' ] = atoms .segids
260
+ attrs [" chainIDs" ] = atoms .segids
244
261
except (NoDataError , AttributeError ):
245
- attrs [' chainIDs' ] = itertools .cycle (('' ,))
262
+ attrs [" chainIDs" ] = itertools .cycle (("" ,))
246
263
missing_topology .append (attr )
247
264
if missing_topology :
248
265
warnings .warn (
249
266
"Supplied AtomGroup was missing the following attributes: "
250
267
"{miss}. These will be written with default values. "
251
- "" .format (miss = ', ' .join (missing_topology )))
268
+ "" .format (miss = ", " .join (missing_topology ))
269
+ )
252
270
253
- with util .openany (self .filename , 'wt' ) as crd :
271
+ with util .openany (self .filename , "wt" ) as crd :
254
272
# 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
+ )
257
278
crd .write ("*\n " )
258
279
259
280
# Write NUMATOMS
260
281
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 ))
262
283
else :
263
- crd .write (self .fmt [' NUMATOMS' ].format (n_atoms ))
284
+ crd .write (self .fmt [" NUMATOMS" ].format (n_atoms ))
264
285
265
286
# Write all atoms
266
287
267
288
current_resid = 1
268
- resids = attrs [' resids' ]
289
+ resids = attrs [" resids" ]
269
290
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 ]:
273
300
current_resid += 1
274
301
275
302
# Truncate numbers
276
303
serial = util .ltruncate_int (i + 1 , serial_len )
277
304
resid = util .ltruncate_int (resid , resid_len )
278
305
current_resid = util .ltruncate_int (current_resid , totres_len )
279
306
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
+ )
0 commit comments