31
31
# fmt: on
32
32
33
33
34
+ def _format_large_time (mol , ext ):
35
+ step = mol .step
36
+ time = mol .time
37
+ nframes = mol .numFrames
38
+
39
+ if len (step ) == 1 :
40
+ trajfreq = step [0 ]
41
+ else :
42
+ trajfreq = step [1 ] - step [0 ]
43
+
44
+ if step [- 1 ] != step [- 1 ].astype (np .uint32 ):
45
+ logger .warning (
46
+ f"Molecule.step contains values too large to be written to a { ext } file. They will be renumbered starting from 1."
47
+ )
48
+ step = np .arange (1 , nframes + 1 , dtype = np .uint32 )
49
+ else :
50
+ step = step .astype (np .uint32 )
51
+
52
+ time = time / 1e3 # convert from fs to ps
53
+ if time [- 1 ] != time [- 1 ].astype (np .float32 ):
54
+ logger .warning (
55
+ f"Molecule.time contains values too large to be written to a { ext } file. They will be renumbered starting from 0."
56
+ )
57
+ if trajfreq == 0 :
58
+ raise AssertionError ("The trajectory step should not be 0" )
59
+ timestep = (mol .fstep / trajfreq ) / 1e-6
60
+ time = (mol .time - ((mol .step [0 ] - trajfreq ) * timestep )) / 1e3
61
+
62
+ return step , time
63
+
64
+
34
65
def _format_pdb_name (name , resname , element = None ):
35
66
name = name [:4 ]
36
67
first_col = f"{ name :<4} "
@@ -263,9 +294,10 @@ def XTCwrite(mol, filename):
263
294
if os .path .isfile (filename ):
264
295
os .unlink (filename )
265
296
297
+ step , time = _format_large_time (mol , "XTC" )
298
+
266
299
box = box .astype (np .float32 ) * 0.1
267
- step = step .astype (np .int32 )
268
- time = time .astype (np .float32 ) / 1e3 # Convert from fs to ps
300
+ time = time .astype (np .float32 )
269
301
coords = coords .astype (np .float32 ) * 0.1 # Convert from A to nm
270
302
if not box .flags ["C_CONTIGUOUS" ]:
271
303
box = np .ascontiguousarray (box )
@@ -671,6 +703,16 @@ def DCDwrite(mol, filename):
671
703
nsavc = int (mol .step [1 ] - mol .step [0 ])
672
704
fstep = mol .fstep * 1000 # ns to ps
673
705
delta = fstep / nsavc / 0.04888821 # Conversion factor found in OpenMM
706
+ if mol .step [0 ] != mol .step [0 ].astype (np .int32 ):
707
+ logger .warning (
708
+ "Molecule.step contains values too large to be written to DCD file. They will be renumbered starting from 1."
709
+ )
710
+ istart //= nsavc
711
+ delta *= nsavc
712
+ nsavc = 1
713
+ # If it's still too large just start from 1
714
+ if istart != np .array (istart ).astype (np .int32 ):
715
+ istart = 1
674
716
except Exception :
675
717
istart = 0
676
718
nsavc = 1
@@ -699,8 +741,7 @@ def TRRwrite(mol, filename):
699
741
from moleculekit .trr import TRRTrajectoryFile
700
742
701
743
xyz = np .transpose (mol .coords , (2 , 0 , 1 )) / 10 # Convert Angstrom to nm
702
- time = mol .time / 1000 # Convert fs to ps
703
- step = mol .step
744
+ step , time = _format_large_time (mol , "TRR" )
704
745
boxvectors = np .transpose (mol .boxvectors , (2 , 0 , 1 )) / 10 # Angstrom to nm
705
746
with TRRTrajectoryFile (filename , "w" ) as fh :
706
747
fh .write (xyz , time = time , step = step , box = boxvectors , lambd = None )
@@ -728,8 +769,10 @@ def NETCDFwrite(mol, filename):
728
769
)
729
770
n_frames , n_atoms = coordinates .shape [0 ], coordinates .shape [1 ]
730
771
772
+ step , time = _format_large_time (mol , "NETCDF" )
773
+
731
774
time = ensure_type (
732
- mol . time / 1000 , # Convert from fs to ps
775
+ time , # In ps
733
776
np .float32 ,
734
777
1 ,
735
778
"time" ,
@@ -739,7 +782,7 @@ def NETCDFwrite(mol, filename):
739
782
add_newaxis_on_deficient_ndim = True ,
740
783
)
741
784
step = ensure_type (
742
- mol . step ,
785
+ step ,
743
786
np .int32 ,
744
787
1 ,
745
788
"step" ,
@@ -984,7 +1027,7 @@ def MDTRAJwrite(mol, filename):
984
1027
traj = Trajectory (
985
1028
xyz = np .transpose (mol .coords , (2 , 0 , 1 )) / 10 , # Ang to nm
986
1029
topology = traj .topology ,
987
- time = time ,
1030
+ time = time . astype ( np . float32 ) ,
988
1031
unitcell_lengths = box ,
989
1032
unitcell_angles = boxangles ,
990
1033
)
0 commit comments