def bin_atoms(self):
        '''This function bins the Atoms into fixed-size sections of the protein space in 3D.'''
        low_point = numpy.array([self.min_x, self.min_y, self.min_z])
        high_point = numpy.array([self.max_x, self.max_y, self.max_z])
        atom_bin_dimensions = numpy.ceil((high_point - low_point) / self.bin_size)
        self.atom_bin_dimensions = (int(atom_bin_dimensions[0]) - 1, int(atom_bin_dimensions[1]) - 1, int(atom_bin_dimensions[2]) - 1)
        atom_bins = []
        for x in range(int(atom_bin_dimensions[0])):
            atom_bins.append([])
            for y in range(int(atom_bin_dimensions[1])):
                atom_bins[x].append([])
                for z in range(int(atom_bin_dimensions[2])):
                    atom_bins[x][y].append(Bin(x, y, z))
        for serial_number, atom in self.atoms.iteritems():
            bin_location = numpy.trunc((atom.point - low_point) / self.bin_size)
            bin = atom_bins[int(bin_location[0])][int(bin_location[1])][int(bin_location[2])]
            bin.append(atom)
            atom.set_bin(bin)
        if self.safe_mode:
            num_atoms = 0
            for x in range(int(atom_bin_dimensions[0])):
                for y in range(int(atom_bin_dimensions[1])):
                    for z in range(int(atom_bin_dimensions[2])):
                        num_atoms += len(atom_bins[x][y][z])
            assert(num_atoms == len(self.atoms))
        blank_section = ()
        for x in range(int(atom_bin_dimensions[0])):
            for y in range(int(atom_bin_dimensions[1])):
                for z in range(int(atom_bin_dimensions[2])):
                    if not atom_bins[x][y][z]:
                        atom_bins[x][y][z] = blank_section
        self.atom_bins = atom_bins