Coverage for gamdpy/configuration/old_input_output.py: 11%
150 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
1import h5py
2import gzip
3import numpy as np
4import numba
5import math
6from numba import cuda
8from .colarray import colarray
9from ..simulation_boxes import Orthorhombic, LeesEdwards
10from .topology import Topology, duplicate_topology, replicate_topologies
11from ..simulation.get_default_compute_flags import get_default_compute_flags
12from .Configuration import Configuration
14'''
15def configuration_to_hdf5(configuration: Configuration, filename: str, meta_data=None) -> None:
16 """ Write a configuration to a HDF5 file
18 Parameters
19 ----------
21 configuration : gamdpy.Configuration
22 a gamdpy configuration object
24 filename : str
25 filename of the output file .h5
27 meta_data : str
28 not used in the function so far (default None)
30 Example
31 -------
33 >>> import os
34 >>> import gamdpy as gp
35 >>> conf = gp.Configuration(D=3)
36 >>> conf.make_positions(N=10, rho=1.0)
37 >>> gp.configuration_to_hdf5(configuration=conf, filename="final.h5")
38 >>> os.remove("final.h5") # Removes file (for doctests)
40 """
42 if not filename.endswith('.h5'):
43 filename += '.h5'
44 with h5py.File(filename, "w") as f:
45 f.attrs['simbox'] = configuration.simbox.get_lengths()
46 if meta_data is not None:
47 for item in meta_data:
48 f.attrs[item] = meta_data[item]
50 ds_r = f.create_dataset('r', shape=(configuration.N, configuration.D), dtype=np.float32)
51 ds_v = f.create_dataset('v', shape=(configuration.N, configuration.D), dtype=np.float32)
52 ds_p = f.create_dataset('ptype', shape=(configuration.N), dtype=np.int32)
53 ds_m = f.create_dataset('m', shape=(configuration.N), dtype=np.float32)
54 ds_r_im = f.create_dataset('r_im', shape=(configuration.N, configuration.D), dtype=np.int32)
55 ds_r[:] = configuration['r']
56 ds_v[:] = configuration['v']
57 ds_p[:] = configuration.ptype
58 ds_m[:] = configuration['m']
59 ds_r_im[:] = configuration.r_im
60'''
63def configuration_from_hdf5(filename: str, reset_images=False, compute_flags=None) -> Configuration:
64 """ Read a configuration from a HDF5 file
66 Parameters
67 ----------
69 filename : str
70 filename of the input file .h5
72 reset_images : bool
73 if True set the images to zero (default False)
75 Returns
76 -------
78 configuration : gamdpy.Configuration
79 a gamdpy configuration object
81 Example
82 -------
84 >>> import gamdpy as gp
85 >>> conf = gp.configuration_from_hdf5("examples/Data/final.h5")
86 >>> print(conf.D, conf.N, conf['r'][0]) # Print number of dimensions D, number of particles N and position of first particle
87 3 10 [-0.7181449 -1.3644753 -1.5799187]
89 """
91 if not filename.endswith('.h5'):
92 raise ValueError('Filename not in HDF5 format')
93 with h5py.File(filename, "r") as f:
94 lengths = f.attrs['simbox']
95 r = f['r'][:]
96 v = f['v'][:]
97 ptype = f['ptype'][:]
98 m = f['m'][:]
99 r_im = f['r_im'][:]
100 N, D = r.shape
101 configuration = Configuration(D=D, compute_flags=compute_flags)
102 configuration.simbox = Orthorhombic(D, lengths)
103 configuration['r'] = r
104 configuration['v'] = v
105 configuration.ptype = ptype
106 configuration['m'] = m
107 if reset_images:
108 configuration.r_im = np.zeros((N, D), dtype=np.int32)
109 else:
110 configuration.r_im = r_im
111 return configuration
114'''
115def configuration_from_hdf5_group(f, group_name, reset_images=False, compute_flags=None) -> Configuration:
116 """ Read a configuration from an open HDF5 file identified by group-name
118 Parameters
119 ----------
120 f : HDF5 File
121 open HDF5 open, as returned by h5py.File()
123 reset_images : bool
124 if True set the images to zero (default False)
126 Returns
127 -------
129 configuration : gamdpy.Configuration
130 a gamdpy configuration object
133 Example:
134 --------
136 >>> import gamdpy as gp
137 >>> output_file = h5py.File('examples/Data/LJ_r0.973_T0.70_toread.h5')
138 >>> conf = gp.configuration_from_hdf5_group(output_file, 'restarts/restart0000')
139 >>> print(conf.D, conf.N, conf['r'][0]) # Print number of dimensions D, number of particles N and position of first particle
140 3 2048 [-6.384221 -6.3622074 -6.3125153]
142 """
145 vectors_array = f[group_name]['vectors'][:]
146 _, N, D = vectors_array.shape
147 configuration = Configuration(D=D, N=N, compute_flags=compute_flags)
150 configuration.vector_columns = f[group_name]['vectors'].attrs['vector_columns']
151 configuration.scalar_columns = f[group_name]['scalars'].attrs['scalar_columns']
153 configuration.ptype = f[group_name]['ptype'][:]
156 scalars_array = f[group_name]['scalars'][:]
157 configuration.scalars = scalars_array
158 configuration.vectors.array = vectors_array
161 simbox_name = f[group_name].attrs['simbox_name']
162 simbox_data = f[group_name].attrs['simbox_data']
164 if simbox_name == 'Orthorhombic':
165 configuration.simbox = Orthorhombic(D, simbox_data)
166 elif simbox_name == 'LeesEdwards':
167 box_shift_image = {True:0, False: int(simbox_data[D+1])} [reset_images]
168 configuration.simbox = LeesEdwards(D, simbox_data[:D], simbox_data[D], box_shift_image)
169 else:
170 raise ValueError('simbox_name %s not recognized in group %s' % (simbox_name, group_name))
172 if reset_images:
173 configuration.r_im = np.zeros((N, D), dtype=np.int32)
174 else:
175 configuration.r_im = f[group_name]['r_im'][:]
176 return configuration
177'''
179def configuration_to_rumd3(configuration: Configuration, filename: str) -> None:
180 """ Write a configuration to a RUMD3 file
182 Parameters
183 ----------
185 configuration : gamdpy.Configuration
186 a gamdpy configuration object
188 filename : str
189 filename of the output file .xyz.gz
191 Example
192 -------
194 >>> import os
195 >>> import gamdpy as gp
196 >>> conf = gp.Configuration(D=3)
197 >>> conf.make_positions(N=10, rho=1.0)
198 >>> gp.configuration_to_rumd3(configuration=conf, filename="restart.xyz.gz")
199 >>> os.remove("restart.xyz.gz") # Removes file (for doctests)
201 """
202 N = configuration.N
203 if configuration.D != 3:
204 raise ValueError("Only D==3 is compatibale with RUMD-3")
206 r = configuration['r']
207 v = configuration['v']
208 ptype = configuration.ptype
209 m = configuration['m']
210 r_im = configuration.r_im
212 num_types = max(ptype) + 1 # assumes consecutive types starting from zero
213 # find corresponding masses assuming unique mass for each type as required by RUMD-3
214 masses = np.ones(num_types, dtype=np.float32)
215 for type in range(num_types):
216 type_first_idx = np.where(ptype == type)[0][0]
217 masses[type] = m[type_first_idx]
219 sim_box = configuration.simbox.get_lengths()
220 if not filename.endswith('.gz'):
221 filename += '.gz'
223 with gzip.open(filename, 'wt') as f:
224 f.write('%d\n' % N)
225 comment_line = 'ioformat=2 numTypes=%d' % (num_types)
226 comment_line += ' sim_box=RectangularSimulationBox,%f,%f,%f' % (sim_box[0], sim_box[1], sim_box[2])
227 comment_line += ' mass=%f' % (masses[0])
228 for mass in masses[1:]:
229 comment_line += ',%f' % mass
230 comment_line += ' columns=type,x,y,z,imx,imy,imz,vx,vy,vz'
231 comment_line += '\n'
232 f.write(comment_line)
233 for idx in range(N):
234 line_out = '%d %.9f %.9f %.9f %d %d %d %f %f %f\n' % (
235 ptype[idx], r[idx, 0], r[idx, 1], r[idx, 2], r_im[idx, 0], r_im[idx, 1], r_im[idx, 2], v[idx, 0],
236 v[idx, 1],
237 v[idx, 2])
238 f.write(line_out)
241def configuration_from_rumd3(filename: str, reset_images=False, compute_flags=None) -> Configuration:
242 """ Read a configuration from a RUMD3 file
244 Parameters
245 ----------
247 filename : str
248 filename of the output file .xyz.gz
250 Returns
251 -------
253 configuration : gamdpy.Configuration
254 a gamdpy configuration object
256 Example
257 -------
259 >>> import gamdpy as gp
260 >>> conf = gp.configuration_from_rumd3("examples/Data/NVT_N4000_T2.0_rho1.2_KABLJ_rumd3/TrajectoryFiles/restart0000.xyz.gz")
261 >>> print(conf.D, conf.N, conf['r'][0]) # Print number of dimensions D, number of particles N and position of first particle
262 3 4000 [ 7.197245 6.610052 -4.7467813]
264 """
265 with gzip.open(filename) as f:
266 line1 = f.readline().decode()
267 N = int(line1)
269 line2 = f.readline().decode()
270 meta_data_items = line2.split()
271 meta_data = {}
272 for item in meta_data_items:
273 key, val = item.split("=")
274 meta_data[key] = val
276 num_types = int(meta_data['numTypes'])
277 masses = [float(x) for x in meta_data['mass'].split(',')]
278 assert len(masses) == num_types
279 if meta_data['ioformat'] == '1':
280 lengths = np.array([float(x) for x in meta_data['boxLengths'].split(',')], dtype=np.float32)
281 else:
282 assert meta_data['ioformat'] == '2'
283 sim_box_data = meta_data['sim_box'].split(',')
284 sim_box_type = sim_box_data[0]
285 sim_box_params = [float(x) for x in sim_box_data[1:]]
286 assert sim_box_type == 'RectangularSimulationBox'
287 lengths = np.array(sim_box_params)
288 # TO DO: handle LeesEdwards sim box
289 assert meta_data['columns'].startswith('type,x,y,z,imx,imy,imz')
290 has_velocities = (meta_data['columns'].startswith('type,x,y,z,imx,imy,imz,vx,vy,vz'))
291 type_array = np.zeros(N, dtype=np.int32)
292 r_array = np.zeros((N, 3), dtype=np.float32)
293 im_array = np.zeros((N, 3), dtype=np.int32)
294 v_array = np.zeros((N, 3), dtype=np.float32)
295 m_array = np.ones(N, dtype=np.float32)
297 for idx in range(N):
298 p_data = f.readline().decode().split()
299 ptype = int(p_data[0])
300 type_array[idx] = ptype
301 r_array[idx, :] = [float(x) for x in p_data[1:4]]
302 if not reset_images:
303 im_array[idx, :] = [int(x) for x in p_data[4:7]]
304 if has_velocities:
305 v_array[idx, :] = [float(x) for x in p_data[7:10]]
306 m_array[idx] = masses[ptype]
308 configuration = Configuration(D=3, compute_flags=compute_flags)
309 configuration.simbox = Orthorhombic(3, lengths)
310 configuration['r'] = r_array
311 configuration['v'] = v_array
312 configuration.r_im = im_array
313 configuration.ptype = type_array
314 configuration['m'] = m_array
316 return configuration
319def configuration_to_lammps(configuration, timestep=0) -> str:
320 """ Convert a configuration to a string formatted as LAMMPS dump file
322 Parameters
323 ----------
325 configuration : gamdpy.Configuration
326 a gamdpy configuration object
328 timestep : float
329 time at which the configuration is saved
331 Returns
332 -------
334 str
335 string formatted as LAMMPS dump file
337 Example
338 -------
340 >>> import gamdpy as gp
341 >>> conf = gp.Configuration(D=3)
342 >>> conf.make_positions(N=10, rho=1.0)
343 >>> lmp_dump = gp.configuration_to_lammps(configuration=conf)
345 """
346 D = configuration.D
347 if D != 3 and D!=2:
348 raise ValueError('Only 3D and 2D configurations are supported')
349 masses = configuration['m']
350 positions = configuration['r']
351 image_coordinates = configuration.r_im
352 forces = configuration['f']
353 velocities = configuration['v']
354 ptypes = configuration.ptype
355 simulation_box = configuration.simbox.get_lengths()
357 # Header
358 header = f'ITEM: TIMESTEP\n{timestep:d}\n'
359 number_of_atoms = positions.shape[0]
360 header += f'ITEM: NUMBER OF ATOMS\n{number_of_atoms:d}\n'
361 header += f'ITEM: BOX BOUNDS pp pp pp\n'
362 for k in range(D):
363 header += f'{-simulation_box[k] / 2:e} {simulation_box[k] / 2:e}\n'
364 if D==2:
365 header += f'{-1 / 2:e} {1 / 2:e}\n'
366 # Atoms
367 atom_data = 'ITEM: ATOMS id type mass x y z ix iy iz vx vy vz fx fy fz'
368 for i in range(number_of_atoms):
369 atom_data += f'\n{i + 1:d} {ptypes[i] + 1:d} {masses[i]:f} '
370 for k in range(D):
371 atom_data += f'{positions[i, k]:f} '
372 if D==2:
373 atom_data += f'{0.0:f} '
374 for k in range(D):
375 atom_data += f'{image_coordinates[i, k]:d} '
376 if D==2:
377 atom_data += f'{0.0:f} '
378 for k in range(D):
379 atom_data += f'{velocities[i, k]:f} '
380 if D==2:
381 atom_data += f'{0.0:f} '
382 for k in range(D):
383 atom_data += f'{forces[i, k]:f} '
384 if D==2:
385 atom_data += f'{0.0:f} '
386 #atom_data += '\n'
387 # Combine header and atom lengths
388 lammps_dump = header + atom_data
389 return lammps_dump