for residue in source_residues:
             for all heavy atoms in residue
               find all heavy atoms within radius which are within residues (ATOM records)
           for all heavy atoms found
             determing the associated residue
           for all found residues not in source_residues
             identify all non-backbone atoms
           return the non-backbone atoms

def find_sidechain_atoms_within_radius_of_residue_objects(self, source_residues, search_radius, find_ATOM_atoms = True, find_HETATM_atoms = False, restrict_to_CA = False):
        '''for residue in source_residues:
             for all heavy atoms in residue
               find all heavy atoms within radius which are within residues (ATOM records)
           for all heavy atoms found
             determing the associated residue
           for all found residues not in source_residues
             identify all non-backbone atoms
           return the non-backbone atoms'''

        atom_hit_cache = set()
        for residue in source_residues:
            if find_ATOM_atoms:
                for aatom in residue.get('ATOM'):
                    self.find_heavy_atoms_near_atom(aatom, search_radius, atom_hit_cache = atom_hit_cache, restrict_to_CA = restrict_to_CA)
            if find_HETATM_atoms:
                for hatom in residue.get('HETATM'):
                    self.find_heavy_atoms_near_atom(hatom, search_radius, atom_hit_cache = atom_hit_cache, restrict_to_CA = restrict_to_CA)

        # Get the list of source_residues
        loop_residue_ids = set()
        for sres in source_residues:
            loop_residue_ids.add(sres.id())

        # Get the list of atoms to be removed (all sidechain atoms - including non-heavy atoms - of the found residues which are not in source_residues)
        sidechain_atom_serial_numbers = set()
        nearby_residues = set()
        nearby_residue_ids = set()
        for a in atom_hit_cache:
            residue_id = a.residue.id()
            if residue_id not in loop_residue_ids:
                nearby_residues.add(a.residue)
                nearby_residue_ids.add(residue_id)
        for nearby_residue in nearby_residues:
            for aatom in nearby_residue.get('ATOM'):
                if aatom.name not in backbone_atoms:
                    sidechain_atom_serial_numbers.add(aatom.serial_number)
        assert(len(nearby_residue_ids.intersection(loop_residue_ids)) == 0)
        return sidechain_atom_serial_numbers