Skip to content

Commit dcb7fa6

Browse files
authored
Merge pull request #120 from MolarVerse/dev
Release: v1.2.3
2 parents 5f0f795 + 29cbff3 commit dcb7fa6

File tree

19 files changed

+570
-81
lines changed

19 files changed

+570
-81
lines changed
370 Bytes
Binary file not shown.

PQAnalysis/atomic_system/atomic_system.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
from .exceptions import AtomicSystemError
3737

3838

39-
4039
class AtomicSystem(
4140
_PropertiesMixin,
4241
_StandardPropertiesMixin,
@@ -194,7 +193,7 @@ def __init__(
194193
self._stress = stress
195194
self._cell = cell
196195

197-
#TODO: check why dynamic formatting does
196+
# TODO: check why dynamic formatting does
198197
# not work here for "AtomicSystem"
199198
#
200199
# @runtime_type_checking
@@ -403,15 +402,15 @@ def center_of_mass_residues(self) -> "AtomicSystem":
403402
-------
404403
AtomicSystem
405404
The center of mass of the residues in the system.
406-
405+
407406
Raises:
408407
-------
409408
AtomicSystemError
410409
If the number of residues in the system is not a
411410
multiple of the number of atoms.
412411
PQNotImplementedError
413412
if system has forces, velocities or charges.
414-
413+
415414
TODO:
416415
-----
417416
Include also center of mass velocities, forces and so on...
@@ -519,6 +518,34 @@ def compute_com_atomic_system(self, group=None) -> "AtomicSystem":
519518

520519
return AtomicSystem(pos=np.array(pos), atoms=names, cell=self.cell)
521520

521+
def randomize_positions(
522+
self,
523+
stdev: float = 0.001,
524+
seed: int | None = None,
525+
) -> "AtomicSystem":
526+
"""
527+
Randomizes the positions of the atoms in the system with a normal distribution.
528+
529+
Parameters
530+
----------
531+
stdev : float, optional
532+
The standard deviation of the random displacements, by default 0.001
533+
seed : int, optional
534+
The seed for the random number generator, by default None
535+
536+
Returns
537+
-------
538+
AtomicSystem
539+
The AtomicSystem with the randomized positions.
540+
"""
541+
542+
if seed is not None:
543+
np.random.seed(seed)
544+
545+
self.pos += np.random.normal(scale=stdev, size=self.pos.shape)
546+
547+
return self
548+
522549
def copy(self) -> "AtomicSystem":
523550
"""
524551
Returns a copy of the AtomicSystem.

PQAnalysis/cli/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .traj2qmcfc import Traj2QMCFCCLI
99
from .traj2box import Traj2BoxCLI
1010
from .rst2xyz import Rst2XYZCLI
11+
from .xyz2rst import XYZ2RstCLI
1112
from .rdf import RDFCLI
1213
from .gen2xyz import GEN2XYZCLI
1314
from .continue_input import ContinueInputCLI
@@ -43,6 +44,7 @@ def main():
4344
GEN2XYZCLI.program_name(): GEN2XYZCLI,
4445
RDFCLI.program_name(): RDFCLI,
4546
Rst2XYZCLI.program_name(): Rst2XYZCLI,
47+
XYZ2RstCLI.program_name(): XYZ2RstCLI,
4648
Traj2BoxCLI.program_name(): Traj2BoxCLI,
4749
Traj2QMCFCCLI.program_name(): Traj2QMCFCCLI,
4850
XYZ2GENCLI.program_name(): XYZ2GENCLI,

PQAnalysis/cli/xyz2rst.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""
2+
.. _cli.rst2xyz:
3+
4+
Command Line Tool for Converting XYZ Files to Restart Files
5+
-----------------------------------------------------------
6+
7+
8+
"""
9+
10+
from PQAnalysis.io import xyz2rst
11+
from PQAnalysis.config import code_base_url
12+
from ._argument_parser import _ArgumentParser
13+
from ._cli_base import CLIBase
14+
15+
__outputdoc__ = """
16+
17+
This command line tool can be used to convert xyz files to restart files.
18+
19+
"""
20+
21+
__epilog__ = "\n"
22+
__epilog__ += "For more information on required and optional input file keys please visit "
23+
__epilog__ += f"{code_base_url}PQAnalysis.cli.xyz2rst.html."
24+
__epilog__ += "\n"
25+
__epilog__ += "\n"
26+
27+
__doc__ += __outputdoc__
28+
29+
30+
class XYZ2RstCLI(CLIBase):
31+
32+
"""
33+
Command Line Tool for Converting XYZ Files to Restart Files
34+
"""
35+
36+
@classmethod
37+
def program_name(cls) -> str:
38+
"""
39+
Returns the name of the program.
40+
41+
Returns
42+
-------
43+
str
44+
The name of the program.
45+
"""
46+
return 'xyz2rst'
47+
48+
@classmethod
49+
def add_arguments(cls, parser: _ArgumentParser) -> None:
50+
"""
51+
Adds the arguments to the parser.
52+
53+
Parameters
54+
----------
55+
parser : _ArgumentParser
56+
The parser to which the arguments should be added.
57+
"""
58+
parser.parse_output_file()
59+
60+
parser.add_argument(
61+
'xyz_file',
62+
type=str,
63+
help='The xyz file to be converted.'
64+
)
65+
66+
parser.add_argument(
67+
'--velocity_file',
68+
type=str,
69+
default=None,
70+
help='The velocity file to be converted.'
71+
)
72+
73+
parser.add_argument(
74+
'--force_file',
75+
type=str,
76+
default=None,
77+
help='The force file to be converted.'
78+
)
79+
80+
parser.add_argument(
81+
'--randomize',
82+
type=float,
83+
default=0.0,
84+
help='Randomize the atom order. Default is 0.0.'
85+
)
86+
87+
parser.parse_engine()
88+
parser.parse_mode()
89+
90+
@classmethod
91+
def run(cls, args):
92+
"""
93+
Runs the command line tool.
94+
95+
Parameters
96+
----------
97+
args : argparse.Namespace
98+
The arguments parsed by the parser.
99+
"""
100+
xyz2rst(
101+
xyz_file=args.xyz_file,
102+
velocity_file=args.velocity_file,
103+
force_file=args.force_file,
104+
randomize=args.randomize,
105+
output=args.output,
106+
md_format=args.engine,
107+
mode=args.mode,
108+
)
109+
110+
111+
def main():
112+
"""
113+
Main function of the xyz2rst command line tool, which is basically just a wrapper
114+
for the xyz2rst function. For more information on the xyz2rst function
115+
please visit :py:func:`PQAnalysis.io.api.xyz2rst`.
116+
"""
117+
parser = _ArgumentParser(description=__outputdoc__, epilog=__epilog__)
118+
119+
XYZ2RstCLI.add_arguments(parser)
120+
121+
args = parser.parse_args()
122+
123+
XYZ2RstCLI.run(args)

PQAnalysis/io/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,6 @@
4848
from .input_file_reader import InputFileFormat
4949

5050
from .api import continue_input_file
51-
from .conversion_api import (gen2xyz, xyz2gen, rst2xyz, traj2box, traj2qmcfc)
51+
from .conversion_api import (
52+
gen2xyz, xyz2gen, rst2xyz, xyz2rst, traj2box, traj2qmcfc)
5253
from .write_api import write, write_box

PQAnalysis/io/conversion_api.py

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
write_gen_file,
2020
read_gen_file,
2121
)
22-
from .restart_file.api import read_restart_file
22+
from .restart_file.api import (
23+
read_restart_file,
24+
write_restart_file
25+
)
2326
from .traj_file.api import write_trajectory
2427

2528

26-
2729
@runtime_type_checking
2830
def gen2xyz(
2931
gen_file: str,
@@ -65,7 +67,6 @@ def gen2xyz(
6567
)
6668

6769

68-
6970
@runtime_type_checking
7071
def xyz2gen(
7172
xyz_file: str,
@@ -110,7 +111,6 @@ def xyz2gen(
110111
)
111112

112113

113-
114114
@runtime_type_checking
115115
def rst2xyz(
116116
restart_file: str,
@@ -152,6 +152,75 @@ def rst2xyz(
152152
)
153153

154154

155+
@runtime_type_checking
156+
def xyz2rst(
157+
xyz_file: str,
158+
velocity_file: str | None = None,
159+
force_file: str | None = None,
160+
randomize: float = 0.0,
161+
random_seed: int | None = 0,
162+
output: str | None = None,
163+
md_format: MDEngineFormat | str = MDEngineFormat.PQ,
164+
mode: FileWritingMode | str = "w"
165+
) -> None:
166+
"""
167+
Converts a xyz file to a restart file and prints it to stdout or writes it to a file.
168+
169+
When the print_box flag is set to True, the box is printed as well.
170+
This means that after the number of atoms the box is printed in the
171+
same line in the format a b c alpha beta gamma.
172+
173+
Parameters
174+
----------
175+
xyz_file : str
176+
The xyz file to be converted.
177+
velocity_file : str | None
178+
The velocity file to be converted. Default is None.
179+
force_file : str | None
180+
The force file to be converted. Default is None.
181+
randomize : float, optional
182+
Randomize the atom order. Default is 0.0.
183+
output : str | None
184+
The output file. If not specified, the output is printed to stdout.
185+
md_format : MDEngineFormat | str, optional
186+
The format of the md engine for the output file. The default is MDEngineFormat.PQ.
187+
mode : FileWritingMode | str, optional
188+
The writing mode, by default "w". The following modes are available:
189+
- "w": write
190+
- "a": append
191+
- "o": overwrite
192+
"""
193+
194+
system = TrajectoryReader(
195+
xyz_file,
196+
md_format=md_format,
197+
traj_format="xyz",
198+
).read()[-1]
199+
200+
if velocity_file is not None:
201+
system.vel = TrajectoryReader(
202+
velocity_file,
203+
md_format=md_format,
204+
traj_format="vel",
205+
).read()[-1].vel
206+
207+
if force_file is not None:
208+
system.forces = TrajectoryReader(
209+
force_file,
210+
md_format=md_format,
211+
traj_format="force",
212+
).read()[-1].forces
213+
214+
if randomize != 0.0:
215+
system.randomize_positions(stdev=randomize, seed=random_seed)
216+
217+
write_restart_file(
218+
atomic_system=system,
219+
filename=output,
220+
md_engine_format=md_format,
221+
mode=mode,
222+
)
223+
155224

156225
@runtime_type_checking
157226
def traj2box(
@@ -201,7 +270,6 @@ def traj2box(
201270
writer.write(trajectory, reset_counter=False)
202271

203272

204-
205273
@runtime_type_checking
206274
def traj2qmcfc(
207275
trajectory_files: List[str],

PQAnalysis/io/restart_file/api.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
from PQAnalysis.core import Residues
66
from PQAnalysis.traj import MDEngineFormat
7+
from PQAnalysis.io.formats import FileWritingMode
78
from PQAnalysis.atomic_system import AtomicSystem
89
from PQAnalysis.type_checking import runtime_type_checking
910

1011
from .restart_reader import RestartFileReader
11-
12+
from .restart_writer import RestartFileWriter
1213

1314

1415
@runtime_type_checking
@@ -51,3 +52,36 @@ def read_restart_file(
5152
)
5253

5354
return reader.read()
55+
56+
57+
@runtime_type_checking
58+
def write_restart_file(
59+
atomic_system: AtomicSystem,
60+
filename: str | None = None,
61+
md_engine_format: MDEngineFormat | str = MDEngineFormat.PQ,
62+
mode: FileWritingMode | str = 'w'
63+
) -> None:
64+
"""
65+
API function for reading a restart file.
66+
67+
Parameters
68+
----------
69+
atomic_system : AtomicSystem
70+
The AtomicSystem object to write.
71+
filename : str
72+
The filename of the restart file.
73+
md_engine_format : MDEngineFormat | str, optional
74+
The format of the restart file,
75+
by default MDEngineFormat.PQ
76+
mode : FileWritingMode | str, optional
77+
The mode of the file. Either 'w' for write,
78+
'a' for append or 'o' for overwrite. The default is 'w'.
79+
"""
80+
81+
writer = RestartFileWriter(
82+
filename=filename,
83+
md_engine_format=md_engine_format,
84+
mode=mode
85+
)
86+
87+
writer.write(atomic_system)

0 commit comments

Comments
 (0)