Example #1
0
    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)
Example #2
0
    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])