2 # This file is part of the GROMACS molecular simulation package.
4 # Copyright (c) 2019,2021, by the GROMACS development team, led by
5 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 # and including many others, as listed in the AUTHORS file in the
7 # top-level source directory and at http://www.gromacs.org.
9 # GROMACS is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2.1
12 # of the License, or (at your option) any later version.
14 # GROMACS is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # Lesser General Public License for more details.
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with GROMACS; if not, see
21 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 # If you want to redistribute modifications to GROMACS, please
25 # consider that scientific software is very special. Version
26 # control is crucial - bugs must be traceable. We will be happy to
27 # consider code for inclusion in the official distribution, but
28 # derived work must not be called official GROMACS. Details are found
29 # in the README & COPYING files - if they are missing, get the
30 # official version at http://www.gromacs.org.
32 # To help us fund GROMACS development, we humbly ask that you cite
33 # the research papers on the package. Check out http://www.gromacs.org.
35 """Provide the high-level interface to the file i/o behaviors in the package.
37 # The submodule is named "fileio" instead of "io" to avoid a
38 # namespace collision with a standard Python module on the default path.
42 __all__ = ['TprFile', 'read_tpr', 'write_tpr_file']
46 from gmxapi import exceptions
49 class TprFile(object):
50 """Handle to a GROMACS simulation run input file.
52 TprFile objects do not have a public interface. The class is used internally
53 to manage simulation input data structures.
56 filename (str): Name of the file with which the object was initialized.
57 mode: File access mode from object creation.
61 def __init__(self, filename: str = None, mode: str = 'r'):
64 File access mode is indicated by 'r' for read-only access.
67 filename (str): Path to a run input file (e.g. 'myfile.tpr')
68 mode (str): File access mode.
71 Currently, TPR files are read-only from the Python interface.
75 raise exceptions.UsageError("TprFile objects must be associated with a file.")
77 raise exceptions.UsageError("TPR files only support read-only access.")
79 self.filename = filename
80 self._tprFileHandle = None
83 # self._tprFileHandle.close()
84 self._tprFileHandle = None
87 return "{}('{}', '{}')".format(self.__class__.__name__, self.filename, self.mode)
90 import gmxapi._gmxapi as _gmxapi
91 self._tprFileHandle = _gmxapi.read_tprfile(self.filename)
94 def __exit__(self, exc_type, exc_val, exc_tb):
99 class _NodeOutput(object):
100 """Implement the `output` attribute of a simulation input node.
103 parameters: Simulation parameters for (re)written TPR file.
104 structure: Atomic details (not yet implemented)
105 topology: Molecular force field details (not yet implemented)
106 state: Simulation state information (not yet implemented)
110 def __init__(self, parameters=None, structure=None, topology=None, state=None):
111 """Initialize getters for output ports."""
112 self.__tprfile = parameters
115 def parameters(self):
116 with self.__tprfile as fh:
117 params = fh._tprFileHandle.params()
122 raise exceptions.ApiError("property not implemented.")
126 raise exceptions.ApiError("property not implemented.")
130 raise exceptions.ApiError("property not implemented.")
133 class _SimulationInput(object):
135 Simulation input interface for a TPR file read by gmx.fileio.read_tpr()
138 parameters: Simulation parameters for (re)written TPR file.
139 structure: Atomic details (not yet implemented)
140 topology: Molecular force field details (not yet implemented)
141 state: Simulation state information (not yet implemented)
145 def __init__(self, tprfile: typing.Union[str, TprFile]):
146 if not isinstance(tprfile, TprFile):
148 tprfile = TprFile(tprfile)
149 except Exception as e:
150 # This class is an implementation detail of TPR file I/O...
151 raise exceptions.ApiError("Must be initialized from a TprFile.") from e
152 assert isinstance(tprfile, TprFile)
153 self.__tprfile = tprfile
154 self.__parameters = None
157 def parameters(self):
158 if self.__parameters is None:
159 with self.__tprfile as fh:
160 self.__parameters = fh._tprFileHandle.params()
161 return self.__parameters
165 raise exceptions.ApiError("property not implemented.")
169 raise exceptions.ApiError("property not implemented.")
173 raise exceptions.ApiError("property not implemented.")
176 def read_tpr(tprfile: typing.Union[str, TprFile]):
178 Get a simulation input object from a TPR run input file.
181 tprfile : TPR input object or filename
184 simulation input object
186 The returned object may be inspected by the user. Simulation input parameters
187 may be extracted through the `parameters` attribute.
190 >>> sim_input = gmx.fileio.read_tpr(tprfile=tprfilename)
191 >>> params = sim_input.parameters.extract()
192 >>> print(params['init-step'])
195 Supports the `read_tpr` gmxapi work graph operation. (not yet implemented)
197 if not isinstance(tprfile, TprFile):
199 tprfile = TprFile(os.fsencode(tprfile), mode='r')
200 except Exception as e:
201 raise exceptions.UsageError("TPR object or file name is required.") from e
203 return _SimulationInput(tprfile)
206 # In initial implementation, we extract the entire TPR file contents through the
207 # TPR-backed GmxMdParams implementation.
208 # Note: this function is not consistent with a gmxapi operation.
209 def write_tpr_file(output, input=None):
211 Create a new TPR file, combining user-provided input.
213 .. versionadded:: 0.0.8
214 Initial version of this tool does not know how to generate a valid simulation
215 run input file from scratch, so it requires input derived from an already valid
218 The simulation input object should provide the gmx simulation_input interface,
219 with output ports for `parameters`, `structure`, `topology`, and `state`, such
223 output : TPR file name to write.
224 input : simulation input data from which to write a simulation run input file.
226 Use this function to write a new TPR file with data updated from an
227 existing TPR file. Keyword arguments are objects that can provide gmxapi
228 compatible access to the necessary simulation input data.
230 In the initial version, data must originate from an existing TPR file, and
231 only simulation parameters may be rewritten. See gmx.fileio.read_tpr()
234 >>> sim_input = gmx.fileio.read_tpr(tprfile=tprfilename)
235 >>> sim_input.parameters.set('init-step', 1)
236 >>> gmx.fileio.write_tpr_file(newfilename, input=sim_input)
239 The interface is in flux.
242 Be consistent about terminology for "simulation state".
243 We are currently using "simulation state" to refer both to the aggregate of
244 data (superset) necessary to launch or continue a simulation _and_ to the
245 extra data (subset) necessary to capture full program state, beyond the
246 model/method input parameters and current phase space coordinates. Maybe we
247 shouldn't expose that as a separate user-accessible object and should instead
248 make it an implementation detail of a wrapper object that has standard
249 interfaces for the non-implementation-dependent encapsulated data.
252 TBD : possibly a completion condition of some sort and/or handle to the new File
254 import gmxapi._gmxapi as _gmxapi
256 # TODO: (Data model) Decide how to find output data sources.
257 if not hasattr(input, 'parameters'):
258 if hasattr(input, 'output'):
259 if hasattr(input.output, 'parameters'):
260 parameters = input.output.parameters
262 raise ValueError("Need output.parameters")
264 raise ValueError("Need output.parameters")
266 parameters = input.parameters
268 if not isinstance(parameters, _gmxapi.SimulationParameters):
269 raise exceptions.TypeError(
270 "You must provide a gmx.core.SimulationParameters object to `parameters` as input.")
271 _gmxapi.write_tprfile(output, parameters)