Open
Description
Because of
ASE changed it's JSON structure format in ~3.16. the format we use is so simplistic that we did not write a dedicated function to do it. The ASE reader on the other hand is backward compatible
one cannot simply use ase to transform the files to json
I used the ase json encoder as basis to make a rascal encoder
https://gitlab.com/ase/ase/blob/master/ase/io/jsonio.py#L25-27
I could put this a bit more cleaned to the python utils. Please give thumbs up if you think this is good or comment if you think we should solve the problem in a different way
import ase.io
import numpy as np
import json
json_frames = {}
frames = ase.io.read('/home/alexgo/datasets/methane.extxyz', ':2')
for frame in frames:
frame.cell = [50, 50, 50]
frame.center()
class RascalEncoder(json.JSONEncoder):
def default(self, obj):
if hasattr(obj, 'todict'):
d = obj.todict()
if not isinstance(d, dict):
raise RuntimeError('todict() of {} returned object of type {} '
'but should have returned dict'
.format(obj, type(d)))
if hasattr(obj, 'ase_objtype'):
d['__ase_objtype__'] = obj.ase_objtype
return d
if isinstance(obj, np.ndarray):
return obj.tolist()
if isinstance(obj, np.integer):
return int(obj)
if isinstance(obj, np.bool_):
return bool(obj)
if isinstance(obj, datetime.datetime):
return {'__datetime__': obj.isoformat()}
if isinstance(obj, complex):
return {'__complex__': (obj.real, obj.imag)}
return json.JSONEncoder.default(self, obj)
for i, frame in enumerate(frames):
json_frames[str(i)] = json.loads(json.dumps(frame, cls=RascalEncoder))
json_frames['ids'] = [i for i in range(len(frames))]
json_frames['nextid'] = len(frames)
with open('/home/alexgo/datasets/methane_test.json', 'w') as f:
json.dump(json_frames, f, indent=2)