def from_hdf(self, hdf = None, group_name = None): # keep hdf structure for version peeking in separate variable, so that # the inherited from_hdf() can properly deal with it h5 = hdf or self.project_hdf5 if group_name: h5 = h5[group_name] if "HDF_VERSION" in h5.list_nodes(): hdf_version = h5["HDF_VERSION"] else: # old versions didn't use to set a HDF version hdf_version = "0.1.0" if hdf_version == "0.1.0": super().from_hdf(hdf=hdf, group_name=group_name) with self.project_hdf5.open("input") as hdf5_input: self.structure = Atoms().from_hdf(hdf5_input) else: GenericJob.from_hdf(self, hdf = hdf, group_name = group_name) self.structure_lst.clear() hdf = self.project_hdf5["structures"] for group in sorted(hdf.list_groups()): structure = Atoms() structure.from_hdf(hdf, group_name = group) self.structure_lst.append(structure)
def _generic_from_hdf(self, hdf, group_name=None): """ Loads dicts, lists and tuples as well as their subclasses from an hdf file Args: hdf: the hdf server group_name: (str) the group name Returns: (obj) the object to return """ # handle special types at first # try a simple load if 'TYPE' not in hdf[group_name].list_nodes(): return hdf[group_name] elif hdf[group_name]['TYPE'] == str(IODictionary): iodict = IODictionary() iodict.from_hdf(hdf, group_name) return iodict elif hdf[group_name]['TYPE'] == str(Atoms): struct = Atoms() struct.from_hdf(hdf, group_name) return struct # FULLNAME will only be present if _generic_to_hdf wrote the underlying object elif 'FULLNAME' in hdf[group_name].keys(): with hdf.open(group_name) as server: from pydoc import locate # convert the class qualifier to a type cls_ = locate(server['FULLNAME']) # handle a dictionary if issubclass(cls_, dict): result = {} # nodes are primitive objects -> that is easy for k in server.list_nodes(): # skip the special nodes if k in ('TYPE', 'FULLNAME'): continue result[k] = server[k] for k in server.list_groups(): # groups are more difficult, since they're other objects -> give it a try result[k] = self._generic_from_hdf(server, group_name=k) # create the instance -> we have to assume a constructor of type cls_(**kwargs) for that # NOTE: if the default constructor is not available this code will break result = cls_(result) return result elif issubclass(cls_, (list, tuple)): result = [] # we have to keep track of the indices -> str.__cmp__ != int.__cmp__ we cannot assume an order indices = [] for k in server.list_nodes(): if k in ('TYPE', 'FULLNAME'): continue # nodes are trivial index = int(k.replace('i_', '')) result.append(server[k]) indices.append(index) # TODO: Since Atoms object appear as a node we might have to call it here too for k in server.list_groups(): # we do have the recursive call here index = int(k.replace('i_', '')) result.append(self._generic_from_hdf(server, group_name=k)) indices.append(index) # sort it, with the keys as indices result = sorted(enumerate(result), key=lambda t: indices[t[0]]) # create the instance, and get rid of the instances result = cls_([val for idx, val in result]) return result else: raise ImportError('Could not locate type(%s)' % server['FULLNAME']) else: raise TypeError('I do not know how to deserialize type(%s)' % hdf[group_name])