From the PDB site:
           The elements of the chemical formula are given in the order following Hill ordering. The order of elements depends
           on whether carbon is present or not. If carbon is present, the order should be: C, then H, then the other elements
           in alphabetical order of their symbol. If carbon is not present, the elements are listed purely in alphabetic order
           of their symbol. This is the 'Hill' system used by Chemical Abstracts.

           WARNING: This assumes that all atoms are in the PDB. This is not usually the case so the formulae will be missing
                    atoms in those cases. To account for some missing data, we merge the element counters to use the most
                    amount of information we can.
                    In general, the FORMUL lines should be used. This function can be used in files with missing headers.

def convert_hetatms_to_Hill_notation(lines, ignore_list = []):#['HOH']):
        '''From the PDB site:
           The elements of the chemical formula are given in the order following Hill ordering. The order of elements depends
           on whether carbon is present or not. If carbon is present, the order should be: C, then H, then the other elements
           in alphabetical order of their symbol. If carbon is not present, the elements are listed purely in alphabetic order
           of their symbol. This is the 'Hill' system used by Chemical Abstracts.

           WARNING: This assumes that all atoms are in the PDB. This is not usually the case so the formulae will be missing
                    atoms in those cases. To account for some missing data, we merge the element counters to use the most
                    amount of information we can.
                    In general, the FORMUL lines should be used. This function can be used in files with missing headers.
           '''

        ignore_list = set(ignore_list)
        hetatms = {}
        for l in lines:
            if l.startswith('HETATM'):
                het_id = l[17:20].strip()
                if het_id in ignore_list:
                    continue
                res_id = l[21:27]
                atom_name = l[12:16]
                alt_loc = l[16]
                hetatms[het_id] = hetatms.get(het_id, {})
                hetatms[het_id][res_id] = hetatms[het_id].get(res_id, {})
                hetatms[het_id][res_id][alt_loc] = hetatms[het_id][res_id].get(alt_loc, ElementCounter())
                hetatms[het_id][res_id][alt_loc].add(atom_name)

        for het_id, res_atoms in hetatms.iteritems():
            res_ids = res_atoms.keys()
            for res_id in res_ids:
                ecs = hetatms[het_id][res_id].values()
                for x in range(1, len(ecs)):
                    ecs[0].merge(ecs[x])
                hetatms[het_id][res_id] = ecs[0]

        str_mapping = {}
        mapping = {}
        for het_id, res_atoms in hetatms.iteritems():
            res_ids = res_atoms.keys()
            for res_id in res_ids:
                Hill_notation = hetatms[het_id][res_id]
                if str_mapping.get(het_id):
                    if not str_mapping[het_id] == str(Hill_notation):
                        mapping[het_id].merge(Hill_notation)
                        str_mapping[het_id] = str(mapping[het_id])
                else:
                    str_mapping[het_id] = str(Hill_notation)
                    mapping[het_id] = Hill_notation
        return mapping