Read a cjson file or a dictionary.

        The cjson format is specified
        `here <https://github.com/OpenChemistry/chemicaljson>`_.

        Args:
            buf (str, dict): If it is a filepath, the data is read from
                filepath. If it is a dictionary, the dictionary is interpreted
                as cjson.

        Returns:
            Cartesian:

def read_cjson(cls, buf):
        """Read a cjson file or a dictionary.

        The cjson format is specified
        `here <https://github.com/OpenChemistry/chemicaljson>`_.

        Args:
            buf (str, dict): If it is a filepath, the data is read from
                filepath. If it is a dictionary, the dictionary is interpreted
                as cjson.

        Returns:
            Cartesian:
        """
        if isinstance(buf, dict):
            data = buf.copy()
        else:
            with open(buf, 'r') as f:
                data = json.load(f)
            assert data['chemical json'] == 0

        n_atoms = len(data['atoms']['coords']['3d'])
        metadata = {}
        _metadata = {}

        coords = np.array(
            data['atoms']['coords']['3d']).reshape((n_atoms // 3, 3))

        atomic_number = constants.elements['atomic_number']
        elements = [dict(zip(atomic_number, atomic_number.index))[x]
                    for x in data['atoms']['elements']['number']]

        try:
            connections = data['bonds']['connections']['index']
        except KeyError:
            pass
        else:
            bond_dict = defaultdict(set)
            for i, b in zip(connections[::2], connections[1::2]):
                bond_dict[i].add(b)
                bond_dict[b].add(i)
            _metadata['bond_dict'] = dict(bond_dict)

        try:
            metadata.update(data['properties'])
        except KeyError:
            pass

        out = cls(atoms=elements, coords=coords, _metadata=_metadata,
                  metadata=metadata)
        return out