Bader Charge Analysis

You must first run a VASP calculation with LCHARG = True and LAECHG = True to run a Bader analysis. The former writes the CHGCAR and the latter writes the AECCAR files.
A Bader charge analysis can be run using the  bader  code by the Henkelman group (or even  Critic2 ). It will tell you the charge on each atom.

Using the Bader Code

The Henkelman group scripts will be available in your PATH on Princeton Research Computing machines after loading the VASP module.
To run a Bader charge analysis with the bader code, do the following:
chgsum.pl AECCAR0 AECCAR2
bader CHGCAR -ref CHGCAR_sum
The charges will be written out to a file called ACF.dat. You can delete the CHGCAR_sum file when you are done running the executable.

Using the Critic2 Code

The following uses  Critic2  to do the Bader charge analysis. It should be very similar to the bader code.
crystal CONTCAR
load AECCAR0
load AECCAR2
load as "$1+$2"
reference 3
load CHGCAR
integrable 4
yt

Note that the Bader charge is the total charge per atom. To get something that is more like an oxidation state, you will need to subtract the number of valence electrons from the displayed charge value. This can be found in the POTCAR. For instance, if you run a calculation with the Br pseudopotential, you will see in the POTCAR file that it has 7 electrons treated as valence. Therefore, a Bader charge of 8.0 would indicate that the Br atom has a net charge of -1.
Script that calculated the partial charges on each atom from the ACF.dat, POSCAR, and POTCAR files
from ase.io import read, write
import numpy as np

bader_charges = np.loadtxt("ACF.dat", skiprows = 2, usecols=4).tolist()
poscar = read("POSCAR")

#grabs line 7, which has the number of each type of element
with open('POSCAR', 'r') as f:
lines = f.readlines()
line7 = lines[6].strip()
line6 = lines[5].strip()
#splits the line up by double space deliner
element_counts = line7.split(' ')
elements = line6.split(' ')

with open('POTCAR', 'r') as f:
potcar_lines = f.readlines()
#creates a dictionary of lists (for each element type in POSCAR)
partials = {}
for el in elements:
partials[el] = []
valance_electrons = []
#gets # of valance electrons for each element from each potcar
for i, line in enumerate(potcar_lines):
if "parameters from" in line:
valance_electrons.append(potcar_lines[i - 1].strip())

#iterates through each element type
for i, el in enumerate(element_counts):
#creates a list of all the popped bader charges of a given element type
popped = []
for j in range(int(el)):
popped.append(bader_charges.pop(0))
#iterates through popped bader charges and subtracts the valance electrons
partial_charges = []
for j in popped:
partial_charges.append(j - float(valance_electrons[i]))

#replaces empty lists with lists of partial charges for each atom
partials[f"{elements[i]}"] = partial_charges