def reionize(self, mol):
log.debug('<STR_LIT>')<EOL>start_charge = Chem.GetFormalCharge(mol)<EOL>for cc in self.charge_corrections:<EOL><INDENT>for match in mol.GetSubstructMatches(cc.smarts):<EOL><INDENT>atom = mol.GetAtomWithIdx(match[<NUM_LIT:0>])<EOL>log.info('<STR_LIT>', cc.name, atom.GetSymbol(), cc.charge)<EOL>atom.SetFormalCharge(cc.charge)<EOL><DEDENT><DEDENT>current_charge = Chem.GetFormalCharge(mol)<EOL>charge_diff = Chem.GetFormalCharge(mol) - start_charge<EOL>if not current_charge == <NUM_LIT:0>:<EOL><INDENT>while charge_diff > <NUM_LIT:0>:<EOL><INDENT>ppos, poccur = self._strongest_protonated(mol)<EOL>if ppos is None:<EOL><INDENT>break<EOL><DEDENT>log.info('<STR_LIT>', self.acid_base_pairs[ppos].name)<EOL>patom = mol.GetAtomWithIdx(poccur[-<NUM_LIT:1>])<EOL>patom.SetFormalCharge(patom.GetFormalCharge() - <NUM_LIT:1>)<EOL>if patom.GetNumExplicitHs() > <NUM_LIT:0>:<EOL><INDENT>patom.SetNumExplicitHs(patom.GetNumExplicitHs() - <NUM_LIT:1>)<EOL><DEDENT>patom.UpdatePropertyCache()<EOL>charge_diff -= <NUM_LIT:1><EOL><DEDENT><DEDENT>already_moved = set()<EOL>while True:<EOL><INDENT>ppos, poccur = self._strongest_protonated(mol)<EOL>ipos, ioccur = self._weakest_ionized(mol)<EOL>if ioccur and poccur and ppos < ipos:<EOL><INDENT>if poccur[-<NUM_LIT:1>] == ioccur[-<NUM_LIT:1>]:<EOL><INDENT>log.warning('<STR_LIT>')<EOL>break<EOL><DEDENT>key = tuple(sorted([poccur[-<NUM_LIT:1>], ioccur[-<NUM_LIT:1>]]))<EOL>if key in already_moved:<EOL><INDENT>log.warning('<STR_LIT>')<EOL>break<EOL><DEDENT>already_moved.add(key)<EOL>log.info('<STR_LIT>', self.acid_base_pairs[ppos].name, self.acid_base_pairs[ipos].name)<EOL>patom = mol.GetAtomWithIdx(poccur[-<NUM_LIT:1>])<EOL>patom.SetFormalCharge(patom.GetFormalCharge() - <NUM_LIT:1>)<EOL>if patom.GetNumImplicitHs() == <NUM_LIT:0> and patom.GetNumExplicitHs() > <NUM_LIT:0>:<EOL><INDENT>patom.SetNumExplicitHs(patom.GetNumExplicitHs() - <NUM_LIT:1>)<EOL><DEDENT>patom.UpdatePropertyCache()<EOL>iatom = mol.GetAtomWithIdx(ioccur[-<NUM_LIT:1>])<EOL>iatom.SetFormalCharge(iatom.GetFormalCharge() + <NUM_LIT:1>)<EOL>if (iatom.GetNoImplicit() or<EOL>((patom.GetAtomicNum() == <NUM_LIT:7> or patom.GetAtomicNum() == <NUM_LIT:15>) and patom.GetIsAromatic()) or<EOL>iatom.GetTotalValence() not in list(Chem.GetPeriodicTable().GetValenceList(iatom.GetAtomicNum()))):<EOL><INDENT>iatom.SetNumExplicitHs(iatom.GetNumExplicitHs() + <NUM_LIT:1>)<EOL><DEDENT>iatom.UpdatePropertyCache()<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>Chem.SanitizeMol(mol)<EOL>return mol<EOL>
Enforce charges on certain atoms, then perform competitive reionization.

        First, charge corrections are applied to ensure, for example, that free metals are correctly ionized. Then, if
        a molecule with multiple acid groups is partially ionized, ensure the strongest acids ionize first.

        The algorithm works as follows:

        - Use SMARTS to find the strongest protonated acid and the weakest ionized acid.
        - If the ionized acid is weaker than the protonated acid, swap proton and repeat.

        :param mol: The molecule to reionize.
        :type mol: rdkit.Chem.rdchem.Mol
        :return: The reionized molecule.
        :rtype: rdkit.Chem.rdchem.Mol