Troubles with 0 oxidation states


We are currently trying to get the oxidation states of various compounds. We are using:


to out put the oxidation states. In most case this works great, but sometimes it outputs compounds with an oxidation state of 0 for each element. An an example of this problem is as follows:

CoO2 outputs as Co4+ O2-2
CuO2 outputs as Cu02 O02
CoO4 outputs as Co0 O04

How can we correctly find the oxidation states for the second and third examples?

Zachary Kaiser


Hi @ZKaiser,

I think this question might be more appropriate on the pymatgen google group (or pymatgen issues page if you believe it’s a bug), or directed to @Anubhav_Jain who developed this feature.

But basically, the reason you are getting oxidation states of zero is because the algorithm can’t find a charge-balanced combination of common oxidation states for the elements present in that composition.

For example, see CoO4: Co has common oxidation states (2, 3) and O has common oxidation states (-2, ), as defined by pymatgen’s Element class. There is no simple combination of these that is charge balanced for this composition. However, it is possible to include less common oxidation states in this analysis by using the all_oxi_states argument, for example:

comp = Composition('CoO4')

This returns:

({'Co': 4.0, 'O': -1.0},
 {'Co': 5.0, 'O': -1.25},
 {'Co': 2.0, 'O': -0.5},
 {'Co': 3.0, 'O': -0.75},
 {'Co': 1.0, 'O': -0.25},
 {'Co': -1.0, 'O': 0.25})

as possible combinations of oxidation state for that composition. More details on how these algorithms work can be found in the pymatgen documentation.

Finally, you should also ask if oxidation state even makes sense in this instance. It’s possible that a formal valence isn’t well defined. Looking up CoO4 in Materials Project gives mp-1079523, which is a material with a very small band gap, and likely has a lot of metallic character. In many cases, an oxidation state of 0 might also be a sensible answer.

Hope this helps,



Matt’s answer covers what I would say

The only other detail I’d add is that the algorithm has a list containing (i) all possible oxidation states and (ii) how likely each oxidation state is. It will only return results that match the list of possible oxidation states, and will rank the results based on overall likelihood.

To override the possible oxidation states, you can either set the “all_oxi_states=True” parameter like Matt suggests or use the “oxi_states_override” parameter to just update the oxidation states on a single element basis

If you want to change the ranking of states relative to one another, you’d need to update the icsd_bv.yaml file in pymatgen that lists the relative occurrence of different oxidation states.